geomerative 0.4.3-java → 2.1.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +2 -0
  3. data/.mvn/extensions.xml +1 -1
  4. data/.mvn/wrapper/maven-wrapper.properties +1 -1
  5. data/CHANGELOG.md +19 -1
  6. data/COPYING.md +1 -1
  7. data/README.md +2 -2
  8. data/Rakefile +2 -15
  9. data/docs/_config.yml +8 -0
  10. data/docs/_includes/head.html +7 -6
  11. data/docs/_includes/header.html +6 -6
  12. data/docs/_includes/icon-github.svg +3 -1
  13. data/docs/_includes/icon-twitter.svg +3 -1
  14. data/docs/_includes/navigation.html +24 -0
  15. data/docs/_sass/_base.scss +79 -79
  16. data/docs/_sass/_layout.scss +137 -137
  17. data/docs/_sass/_syntax-highlighting.scss +64 -64
  18. data/docs/index.html +18 -18
  19. data/examples/README.md +1 -1
  20. data/examples/data/bot1.svg +1 -1
  21. data/examples/data/lion.svg +156 -156
  22. data/examples/data/ruby.svg +1 -1
  23. data/examples/jruby_merge.rb +1 -1
  24. data/examples/{f_agent.rb → library/f_agent/f_agent.rb} +0 -0
  25. data/examples/{font_agent.rb → library/font_agent/font_agent.rb} +2 -1
  26. data/examples/text_on_geomerative_path.rb +3 -2
  27. data/examples/typo_deform.rb +2 -2
  28. data/examples/typo_extra_bright.rb +1 -1
  29. data/geomerative.gemspec +3 -6
  30. data/lib/geomerative/version.rb +1 -1
  31. data/lib/geomerative.jar +0 -0
  32. data/lib/geomerative.rb +10 -10
  33. data/mvnw +234 -0
  34. data/mvnw.cmd +145 -0
  35. data/pom.rb +14 -16
  36. data/pom.xml +13 -19
  37. data/src/geomerative/FastRClip.java +2050 -2334
  38. data/src/geomerative/RClip.java +2237 -2539
  39. data/src/geomerative/RClosest.java +33 -31
  40. data/src/geomerative/RCommand.java +1750 -1758
  41. data/src/geomerative/RContour.java +290 -292
  42. data/src/geomerative/RFont.java +277 -246
  43. data/src/geomerative/RG.java +722 -727
  44. data/src/geomerative/RGeomElem.java +967 -962
  45. data/src/geomerative/RGroup.java +508 -467
  46. data/src/geomerative/RMatrix.java +304 -289
  47. data/src/geomerative/RMesh.java +241 -229
  48. data/src/geomerative/RPath.java +924 -926
  49. data/src/geomerative/RPoint.java +391 -391
  50. data/src/geomerative/RPolygon.java +1017 -1013
  51. data/src/geomerative/RRectangle.java +43 -52
  52. data/src/geomerative/RSVG.java +480 -516
  53. data/src/geomerative/RShape.java +1767 -1777
  54. data/src/geomerative/RStrip.java +173 -176
  55. data/src/geomerative/RStyle.java +197 -194
  56. data/src/module-info.java +4 -0
  57. data/src/org/apache/batik/svggen/font/Font.java +141 -142
  58. data/src/org/apache/batik/svggen/font/Glyph.java +102 -71
  59. data/src/org/apache/batik/svggen/font/Point.java +12 -12
  60. data/src/org/apache/batik/svggen/font/RandomAccessFileEmulator.java +14 -12
  61. data/src/org/apache/batik/svggen/font/table/ClassDef.java +12 -12
  62. data/src/org/apache/batik/svggen/font/table/ClassDefFormat1.java +27 -24
  63. data/src/org/apache/batik/svggen/font/table/ClassDefFormat2.java +20 -17
  64. data/src/org/apache/batik/svggen/font/table/CmapFormat.java +43 -43
  65. data/src/org/apache/batik/svggen/font/table/CmapFormat0.java +33 -26
  66. data/src/org/apache/batik/svggen/font/table/CmapFormat2.java +25 -20
  67. data/src/org/apache/batik/svggen/font/table/CmapFormat4.java +106 -96
  68. data/src/org/apache/batik/svggen/font/table/CmapFormat6.java +36 -32
  69. data/src/org/apache/batik/svggen/font/table/CmapIndexEntry.java +69 -49
  70. data/src/org/apache/batik/svggen/font/table/CmapTable.java +50 -50
  71. data/src/org/apache/batik/svggen/font/table/Coverage.java +19 -19
  72. data/src/org/apache/batik/svggen/font/table/CoverageFormat1.java +30 -27
  73. data/src/org/apache/batik/svggen/font/table/CoverageFormat2.java +26 -24
  74. data/src/org/apache/batik/svggen/font/table/CvtTable.java +16 -16
  75. data/src/org/apache/batik/svggen/font/table/Device.java +32 -32
  76. data/src/org/apache/batik/svggen/font/table/DirectoryEntry.java +39 -39
  77. data/src/org/apache/batik/svggen/font/table/Feature.java +26 -23
  78. data/src/org/apache/batik/svggen/font/table/FeatureList.java +37 -35
  79. data/src/org/apache/batik/svggen/font/table/FeatureRecord.java +22 -22
  80. data/src/org/apache/batik/svggen/font/table/FeatureTags.java +4 -3
  81. data/src/org/apache/batik/svggen/font/table/FpgmTable.java +9 -9
  82. data/src/org/apache/batik/svggen/font/table/GlyfCompositeComp.java +134 -132
  83. data/src/org/apache/batik/svggen/font/table/GlyfCompositeDescript.java +123 -122
  84. data/src/org/apache/batik/svggen/font/table/GlyfDescript.java +44 -44
  85. data/src/org/apache/batik/svggen/font/table/GlyfSimpleDescript.java +110 -109
  86. data/src/org/apache/batik/svggen/font/table/GlyfTable.java +46 -46
  87. data/src/org/apache/batik/svggen/font/table/GlyphDescription.java +25 -13
  88. data/src/org/apache/batik/svggen/font/table/GposTable.java +26 -23
  89. data/src/org/apache/batik/svggen/font/table/GsubTable.java +85 -82
  90. data/src/org/apache/batik/svggen/font/table/HeadTable.java +131 -131
  91. data/src/org/apache/batik/svggen/font/table/HheaTable.java +80 -80
  92. data/src/org/apache/batik/svggen/font/table/HmtxTable.java +50 -49
  93. data/src/org/apache/batik/svggen/font/table/KernSubtable.java +29 -27
  94. data/src/org/apache/batik/svggen/font/table/KernSubtableFormat0.java +35 -32
  95. data/src/org/apache/batik/svggen/font/table/KernSubtableFormat2.java +28 -26
  96. data/src/org/apache/batik/svggen/font/table/KernTable.java +36 -31
  97. data/src/org/apache/batik/svggen/font/table/KerningPair.java +27 -23
  98. data/src/org/apache/batik/svggen/font/table/LangSys.java +28 -26
  99. data/src/org/apache/batik/svggen/font/table/LangSysRecord.java +22 -22
  100. data/src/org/apache/batik/svggen/font/table/Ligature.java +24 -24
  101. data/src/org/apache/batik/svggen/font/table/LigatureSet.java +24 -24
  102. data/src/org/apache/batik/svggen/font/table/LigatureSubst.java +9 -9
  103. data/src/org/apache/batik/svggen/font/table/LigatureSubstFormat1.java +30 -30
  104. data/src/org/apache/batik/svggen/font/table/LocaTable.java +37 -37
  105. data/src/org/apache/batik/svggen/font/table/Lookup.java +41 -40
  106. data/src/org/apache/batik/svggen/font/table/LookupList.java +34 -34
  107. data/src/org/apache/batik/svggen/font/table/LookupSubtableFactory.java +7 -5
  108. data/src/org/apache/batik/svggen/font/table/MaxpTable.java +96 -96
  109. data/src/org/apache/batik/svggen/font/table/NameRecord.java +64 -65
  110. data/src/org/apache/batik/svggen/font/table/NameTable.java +33 -33
  111. data/src/org/apache/batik/svggen/font/table/Os2Table.java +196 -196
  112. data/src/org/apache/batik/svggen/font/table/Panose.java +14 -12
  113. data/src/org/apache/batik/svggen/font/table/PostTable.java +338 -338
  114. data/src/org/apache/batik/svggen/font/table/PrepTable.java +9 -9
  115. data/src/org/apache/batik/svggen/font/table/Program.java +15 -15
  116. data/src/org/apache/batik/svggen/font/table/RangeRecord.java +26 -25
  117. data/src/org/apache/batik/svggen/font/table/Script.java +38 -38
  118. data/src/org/apache/batik/svggen/font/table/ScriptList.java +42 -42
  119. data/src/org/apache/batik/svggen/font/table/ScriptRecord.java +22 -22
  120. data/src/org/apache/batik/svggen/font/table/ScriptTags.java +2 -1
  121. data/src/org/apache/batik/svggen/font/table/SingleSubst.java +15 -16
  122. data/src/org/apache/batik/svggen/font/table/SingleSubstFormat1.java +33 -33
  123. data/src/org/apache/batik/svggen/font/table/SingleSubstFormat2.java +32 -32
  124. data/src/org/apache/batik/svggen/font/table/Table.java +171 -170
  125. data/src/org/apache/batik/svggen/font/table/TableDirectory.java +55 -55
  126. data/src/org/apache/batik/svggen/font/table/TableFactory.java +92 -93
  127. metadata +18 -19
  128. data/.travis.yml +0 -10
  129. data/calculate_torsional_angle.rb +0 -17
@@ -38,1382 +38,1243 @@
38
38
  * SUCH DAMAGE.
39
39
  * ====================================================================
40
40
  */
41
-
42
41
  package geomerative;
43
42
 
44
43
  import java.util.ArrayList;
45
44
  import java.util.List;
46
45
  import geomerative.RClip.OperationType;
46
+ import java.lang.reflect.InvocationTargetException;
47
47
 
48
48
  /**
49
- * <code>Clip</code> is a Java version of the <i>General RPolygon Clipper</i> algorithm
50
- * developed by Alan Murta (gpc@cs.man.ac.uk). The home page for the original source can be
51
- * found at <a href="http://www.cs.man.ac.uk/aig/staff/alan/software/" target="_blank">
49
+ * <code>Clip</code> is a Java version of the <i>General RPolygon Clipper</i>
50
+ * algorithm developed by Alan Murta (gpc@cs.man.ac.uk). The home page for the
51
+ * original source can be found at
52
+ * <a href="http://www.cs.man.ac.uk/aig/staff/alan/software/" target="_blank">
52
53
  * http://www.cs.man.ac.uk/aig/staff/alan/software/</a>.
53
54
  * <p>
54
- * <b><code>polyClass:</code></b> Some of the public methods below take a <code>polyClass</code>
55
- * argument. This <code>java.lang.Class</code> object is assumed to implement the <code>RPolygon</code>
56
- * interface and have a no argument constructor. This was done so that the user of the algorithm
57
- * could create their own classes that implement the <code>RPolygon</code> interface and still uses
58
- * this algorithm.
55
+ * <b><code>polyClass:</code></b> Some of the public methods below take a
56
+ * <code>polyClass</code> argument. This <code>java.lang.Class</code> object is
57
+ * assumed to implement the <code>RPolygon</code> interface and have a no
58
+ * argument constructor. This was done so that the user of the algorithm could
59
+ * create their own classes that implement the <code>RPolygon</code> interface
60
+ * and still uses this algorithm.
59
61
  * <p>
60
- * <strong>Implementation Note:</strong> The converted algorithm does support the <i>difference</i>
61
- * operation, but a public method has not been provided and it has not been tested. To do so,
62
- * simply follow what has been done for <i>intersection</i>.
62
+ * <strong>Implementation Note:</strong> The converted algorithm does support
63
+ * the <i>difference</i>
64
+ * operation, but a public method has not been provided and it has not been
65
+ * tested. To do so, simply follow what has been done for <i>intersection</i>.
63
66
  *
64
- * @author Dan Bridenbecker, Solution Engineering, Inc.
67
+ * @author Dan Bridenbecker, Solution Engineering, Inc.
65
68
  */
66
- class FastRClip
67
- {
69
+ class FastRClip {
68
70
  // -----------------
69
71
  // --- Constants ---
70
72
  // -----------------
71
-
73
+
72
74
  // Maximum precision for floats
73
75
  private static final double GPC_EPSILON = 2.2204460492503131e-016;
74
76
  //private static final float GPC_EPSILON = 1.192092896e-07F;
75
77
  static final String GPC_VERSION = "2.31";
76
-
77
- private static final int LEFT = 0;
78
+
79
+ private static final int LEFT = 0;
78
80
  private static final int RIGHT = 1;
79
-
81
+
80
82
  private static final int ABOVE = 0;
81
83
  private static final int BELOW = 1;
82
-
84
+
83
85
  private static final int CLIP = 0;
84
86
  private static final int SUBJ = 1;
85
-
87
+
86
88
  private static final boolean INVERT_TRISTRIPS = false;
87
-
89
+
88
90
  // ------------------------
89
91
  // --- Member Variables ---
90
92
  // ------------------------
91
-
92
93
  // --------------------
93
94
  // --- Constructors ---
94
95
  // --------------------
95
- /** Creates a new instance of Clip */
96
- private FastRClip()
97
- {
96
+ /**
97
+ * Creates a new instance of Clip
98
+ */
99
+ private FastRClip() {
98
100
  }
99
-
101
+
100
102
  // ----------------------
101
103
  // --- Static Methods ---
102
104
  // ----------------------
103
-
104
-
105
105
  // -----------------------
106
106
  // --- Private Methods ---
107
107
  // -----------------------
108
-
109
108
  /**
110
- * Create a new <code>RPolygon</code> type object using <code>polyClass</code>.
109
+ * Create a new <code>RPolygon</code> type object using
110
+ * <code>polyClass</code>.
111
111
  */
112
- private static RPolygon createNewPoly( Class polyClass )
113
- {
114
- try
115
- {
116
- return (RPolygon)polyClass.newInstance();
117
- }
118
- catch( InstantiationException | IllegalAccessException e )
119
- {
120
- throw new RuntimeException(e);
121
- }
112
+ private static RPolygon createNewPoly(Class polyClass) {
113
+ try {
114
+ return (RPolygon)polyClass.getConstructor().newInstance();
115
+ } catch (IllegalAccessException | IllegalArgumentException | InstantiationException | NoSuchMethodException | SecurityException | InvocationTargetException ex) {
116
+ return null;
117
+ }
122
118
  }
123
119
 
120
+
124
121
  /**
125
- * <code>clip()</code> is the main method of the clipper algorithm.
126
- * This is where the conversion from really begins.
122
+ * <code>clip()</code> is the main method of the clipper algorithm. This is
123
+ * where the conversion from really begins.
127
124
  */
128
- static RPolygon clip( OperationType op, RPolygon subj, RPolygon clip, Class polyClass )
129
- {
125
+ static RPolygon clip(OperationType op, RPolygon subj, RPolygon clip, Class polyClass) {
130
126
  RPolygon result = createNewPoly(polyClass);
131
127
  TopPolygonNode out_poly = new TopPolygonNode(); // used to create resulting RPolygon
132
-
128
+
133
129
  /* Test for trivial NULL result cases */
134
- if( (subj.isEmpty() && clip.isEmpty()) ||
135
- (subj.isEmpty() && ((op == OperationType.GPC_INT) || (op == OperationType.GPC_DIFF))) ||
136
- (clip.isEmpty() && (op == OperationType.GPC_INT)) )
137
- {
138
- return null;
139
- }
140
-
130
+ if ((subj.isEmpty() && clip.isEmpty())
131
+ || (subj.isEmpty() && ((op == OperationType.GPC_INT) || (op == OperationType.GPC_DIFF)))
132
+ || (clip.isEmpty() && (op == OperationType.GPC_INT))) {
133
+ return null;
134
+ }
135
+
141
136
  /* Identify potentialy contributing contours */
142
- if( ((op == OperationType.GPC_INT) || (op == OperationType.GPC_DIFF)) &&
143
- !subj.isEmpty() && !clip.isEmpty() )
144
- {
145
- minimax_test(subj, clip, op);
146
- }
147
-
137
+ if (((op == OperationType.GPC_INT) || (op == OperationType.GPC_DIFF))
138
+ && !subj.isEmpty() && !clip.isEmpty()) {
139
+ minimax_test(subj, clip, op);
140
+ }
141
+
148
142
  /* Build LMT */
149
143
  LmtTable lmt_table = new LmtTable();
150
144
  ScanBeamTreeEntries sbte = new ScanBeamTreeEntries();
151
- if (!subj.isEmpty())
152
- {
153
- build_lmt(lmt_table, sbte, subj, SUBJ, op);
154
- }
155
- if (!clip.isEmpty())
156
- {
157
- build_lmt(lmt_table, sbte, clip, CLIP, op);
158
- }
159
-
145
+ if (!subj.isEmpty()) {
146
+ build_lmt(lmt_table, sbte, subj, SUBJ, op);
147
+ }
148
+ if (!clip.isEmpty()) {
149
+ build_lmt(lmt_table, sbte, clip, CLIP, op);
150
+ }
151
+
160
152
  /* Return a NULL result if no contours contribute */
161
- if (lmt_table.top_node == null)
162
- {
163
- return null;
164
- }
165
-
153
+ if (lmt_table.top_node == null) {
154
+ return null;
155
+ }
156
+
166
157
  /* Build scanbeam table from scanbeam tree */
167
158
  float[] sbt = sbte.build_sbt();
168
-
159
+
169
160
  int parity_clip = LEFT;
170
161
  int parity_subj = LEFT;
171
-
162
+
172
163
  /* Invert clip polygon for difference operation */
173
- if (op == OperationType.GPC_DIFF)
174
- {
175
- parity_clip= RIGHT;
176
- }
177
-
164
+ if (op == OperationType.GPC_DIFF) {
165
+ parity_clip = RIGHT;
166
+ }
167
+
178
168
  LmtNode local_min = lmt_table.top_node;
179
-
169
+
180
170
  AetTree aet = new AetTree();
181
171
  int scanbeam = 0;
182
-
172
+
183
173
  /* Process each scanbeam */
184
- while( scanbeam < sbt.length )
185
- {
186
- /* Set yb and yt to the bottom and top of the scanbeam */
187
- float yb = sbt[scanbeam++];
188
- float yt = 0.0F;
189
- float dy = 0.0F;
190
- if( scanbeam < sbt.length )
191
- {
192
- yt = sbt[scanbeam];
193
- dy = yt - yb;
174
+ while (scanbeam < sbt.length) {
175
+ /* Set yb and yt to the bottom and top of the scanbeam */
176
+ float yb = sbt[scanbeam++];
177
+ float yt = 0.0F;
178
+ float dy = 0.0F;
179
+ if (scanbeam < sbt.length) {
180
+ yt = sbt[scanbeam];
181
+ dy = yt - yb;
182
+ }
183
+
184
+ /* === SCANBEAM BOUNDARY PROCESSING ================================ */
185
+ /* If LMT node corresponding to yb exists */
186
+ if (local_min != null) {
187
+ if (local_min.y == yb) {
188
+ /* Add edges starting at this local minimum to the AET */
189
+ for (EdgeNode edge = local_min.first_bound; (edge != null); edge = edge.next_bound) {
190
+ add_edge_to_aet(aet, edge);
194
191
  }
195
-
196
- /* === SCANBEAM BOUNDARY PROCESSING ================================ */
197
-
198
- /* If LMT node corresponding to yb exists */
199
- if (local_min != null )
200
- {
201
- if (local_min.y == yb)
202
- {
203
- /* Add edges starting at this local minimum to the AET */
204
- for( EdgeNode edge = local_min.first_bound; (edge != null); edge= edge.next_bound)
205
- {
206
- add_edge_to_aet( aet, edge );
207
- }
208
-
209
- local_min = local_min.next;
210
- }
192
+
193
+ local_min = local_min.next;
194
+ }
195
+ }
196
+
197
+ /* Set dummy previous x value */
198
+ float px = -Float.MAX_VALUE;
199
+
200
+ /* Create bundles within AET */
201
+ EdgeNode e0 = aet.top_node;
202
+ EdgeNode e1 = aet.top_node;
203
+
204
+ /* Set up bundle fields of first edge */
205
+ aet.top_node.bundle_above[aet.top_node.type] = (aet.top_node.top_y != yb) ? 1 : 0;
206
+ aet.top_node.bundle_above[((aet.top_node.type == 0) ? 1 : 0)] = 0;
207
+ aet.top_node.bstate_above = BundleState.UNBUNDLED;
208
+
209
+ for (EdgeNode next_edge = aet.top_node.next; (next_edge != null); next_edge = next_edge.next) {
210
+ int ne_type = next_edge.type;
211
+ int ne_type_opp = ((next_edge.type == 0) ? 1 : 0); //next edge type opposite
212
+
213
+ /* Set up bundle fields of next edge */
214
+ next_edge.bundle_above[ne_type] = (next_edge.top_y != yb) ? 1 : 0;
215
+ next_edge.bundle_above[ne_type_opp] = 0;
216
+ next_edge.bstate_above = BundleState.UNBUNDLED;
217
+
218
+ /* Bundle edges above the scanbeam boundary if they coincide */
219
+ if (next_edge.bundle_above[ne_type] == 1) {
220
+ if (EQ(e0.xb, next_edge.xb) && EQ(e0.dx, next_edge.dx) && (e0.top_y != yb)) {
221
+ next_edge.bundle_above[ne_type] ^= e0.bundle_above[ne_type];
222
+ next_edge.bundle_above[ne_type_opp] = e0.bundle_above[ne_type_opp];
223
+ next_edge.bstate_above = BundleState.BUNDLE_HEAD;
224
+ e0.bundle_above[CLIP] = 0;
225
+ e0.bundle_above[SUBJ] = 0;
226
+ e0.bstate_above = BundleState.BUNDLE_TAIL;
211
227
  }
212
-
213
- /* Set dummy previous x value */
214
- float px = -Float.MAX_VALUE;
215
-
216
- /* Create bundles within AET */
217
- EdgeNode e0 = aet.top_node;
218
- EdgeNode e1 = aet.top_node;
219
-
220
- /* Set up bundle fields of first edge */
221
- aet.top_node.bundle_above[ aet.top_node.type ] = (aet.top_node.top_y != yb) ? 1 : 0;
222
- aet.top_node.bundle_above[ ((aet.top_node.type==0) ? 1 : 0) ] = 0;
223
- aet.top_node.bstate_above = BundleState.UNBUNDLED;
224
-
225
- for ( EdgeNode next_edge = aet.top_node.next; (next_edge != null); next_edge = next_edge.next)
226
- {
227
- int ne_type = next_edge.type;
228
- int ne_type_opp = ((next_edge.type==0) ? 1 : 0); //next edge type opposite
229
-
230
- /* Set up bundle fields of next edge */
231
- next_edge.bundle_above[ ne_type ]= (next_edge.top_y != yb) ? 1 : 0;
232
- next_edge.bundle_above[ ne_type_opp ] = 0;
233
- next_edge.bstate_above = BundleState.UNBUNDLED;
234
-
235
- /* Bundle edges above the scanbeam boundary if they coincide */
236
- if ( next_edge.bundle_above[ne_type] == 1 )
237
- {
238
- if (EQ(e0.xb, next_edge.xb) && EQ(e0.dx, next_edge.dx) && (e0.top_y != yb))
239
- {
240
- next_edge.bundle_above[ ne_type ] ^= e0.bundle_above[ ne_type ];
241
- next_edge.bundle_above[ ne_type_opp ] = e0.bundle_above[ ne_type_opp ];
242
- next_edge.bstate_above = BundleState.BUNDLE_HEAD;
243
- e0.bundle_above[CLIP] = 0;
244
- e0.bundle_above[SUBJ] = 0;
245
- e0.bstate_above = BundleState.BUNDLE_TAIL;
246
- }
247
- e0 = next_edge;
248
- }
228
+ e0 = next_edge;
229
+ }
230
+ }
231
+
232
+ int horiz_clip = HState.NH;
233
+ int horiz_subj = HState.NH;
234
+
235
+ int exists_clip = 0;
236
+ int exists_subj = 0;
237
+
238
+ PolygonNode cf = null;
239
+
240
+ /* Process each edge at this scanbeam boundary */
241
+ for (EdgeNode edge = aet.top_node; (edge != null); edge = edge.next) {
242
+ exists_clip = edge.bundle_above[CLIP] + (edge.bundle_below_clip << 1);
243
+ exists_subj = edge.bundle_above[SUBJ] + (edge.bundle_below_subj << 1);
244
+
245
+ if ((exists_clip != 0) || (exists_subj != 0)) {
246
+ /* Set bundle side */
247
+ edge.bside_clip = parity_clip;
248
+ edge.bside_subj = parity_subj;
249
+
250
+ boolean contributing = false;
251
+ int br = 0, bl = 0, tr = 0, tl = 0;
252
+ /* Determine contributing status and quadrant occupancies */
253
+ if ((op == OperationType.GPC_DIFF) || (op == OperationType.GPC_INT)) {
254
+ contributing = ((exists_clip != 0) && ((parity_subj != 0) || (horiz_subj != 0)))
255
+ || ((exists_subj != 0) && ((parity_clip != 0) || (horiz_clip != 0)))
256
+ || ((exists_clip != 0) && (exists_subj != 0) && (parity_clip == parity_subj));
257
+ br = ((parity_clip != 0) && (parity_subj != 0)) ? 1 : 0;
258
+ bl = (((parity_clip ^ edge.bundle_above[CLIP]) != 0)
259
+ && ((parity_subj ^ edge.bundle_above[SUBJ]) != 0)) ? 1 : 0;
260
+ tr = (((parity_clip ^ ((horiz_clip != HState.NH) ? 1 : 0)) != 0)
261
+ && ((parity_subj ^ ((horiz_subj != HState.NH) ? 1 : 0)) != 0)) ? 1 : 0;
262
+ tl = (((parity_clip ^ ((horiz_clip != HState.NH) ? 1 : 0) ^ edge.bundle_below_clip) != 0)
263
+ && ((parity_subj ^ ((horiz_subj != HState.NH) ? 1 : 0) ^ edge.bundle_below_subj) != 0)) ? 1 : 0;
264
+ } else if (op == OperationType.GPC_XOR) {
265
+ contributing = (exists_clip != 0) || (exists_subj != 0);
266
+ br = (parity_clip) ^ (parity_subj);
267
+ bl = (parity_clip ^ edge.bundle_above[CLIP]) ^ (parity_subj ^ edge.bundle_above[SUBJ]);
268
+ tr = (parity_clip ^ ((horiz_clip != HState.NH) ? 1 : 0)) ^ (parity_subj ^ ((horiz_subj != HState.NH) ? 1 : 0));
269
+ tl = (parity_clip ^ ((horiz_clip != HState.NH) ? 1 : 0) ^ edge.bundle_below_clip)
270
+ ^ (parity_subj ^ ((horiz_subj != HState.NH) ? 1 : 0) ^ edge.bundle_below_subj);
271
+ } else if (op == OperationType.GPC_UNION) {
272
+ contributing = ((exists_clip != 0) && (!(parity_subj != 0) || (horiz_subj != 0)))
273
+ || ((exists_subj != 0) && (!(parity_clip != 0) || (horiz_clip != 0)))
274
+ || ((exists_clip != 0) && (exists_subj != 0) && (parity_clip == parity_subj));
275
+ br = ((parity_clip != 0) || (parity_subj != 0)) ? 1 : 0;
276
+ bl = (((parity_clip ^ edge.bundle_above[CLIP]) != 0) || ((parity_subj ^ edge.bundle_above[SUBJ]) != 0)) ? 1 : 0;
277
+ tr = (((parity_clip ^ ((horiz_clip != HState.NH) ? 1 : 0)) != 0)
278
+ || ((parity_subj ^ ((horiz_subj != HState.NH) ? 1 : 0)) != 0)) ? 1 : 0;
279
+ tl = (((parity_clip ^ ((horiz_clip != HState.NH) ? 1 : 0) ^ edge.bundle_below_clip) != 0)
280
+ || ((parity_subj ^ ((horiz_subj != HState.NH) ? 1 : 0) ^ edge.bundle_below_subj) != 0)) ? 1 : 0;
281
+ } else {
282
+ throw new IllegalStateException("Unknown op");
249
283
  }
250
-
251
- int horiz_clip = HState.NH;
252
- int horiz_subj = HState.NH;
253
-
254
- int exists_clip = 0;
255
- int exists_subj = 0;
256
-
257
- PolygonNode cf = null;
258
-
259
- /* Process each edge at this scanbeam boundary */
260
- for ( EdgeNode edge = aet.top_node; (edge != null); edge = edge.next )
261
- {
262
- exists_clip = edge.bundle_above[CLIP] + (edge.bundle_below_clip << 1);
263
- exists_subj = edge.bundle_above[SUBJ] + (edge.bundle_below_subj << 1);
264
-
265
- if( (exists_clip != 0) || (exists_subj != 0) )
266
- {
267
- /* Set bundle side */
268
- edge.bside_clip = parity_clip;
269
- edge.bside_subj = parity_subj;
270
-
271
- boolean contributing = false;
272
- int br=0, bl=0, tr=0, tl=0;
273
- /* Determine contributing status and quadrant occupancies */
274
- if( (op == OperationType.GPC_DIFF) || (op == OperationType.GPC_INT) )
275
- {
276
- contributing= ((exists_clip!=0) && ((parity_subj!=0) || (horiz_subj!=0))) ||
277
- ((exists_subj!=0) && ((parity_clip!=0) || (horiz_clip!=0))) ||
278
- ((exists_clip!=0) && (exists_subj!=0) && (parity_clip == parity_subj));
279
- br = ((parity_clip!=0) && (parity_subj!=0)) ? 1 : 0;
280
- bl = ( ((parity_clip ^ edge.bundle_above[CLIP])!=0) &&
281
- ((parity_subj ^ edge.bundle_above[SUBJ])!=0) ) ? 1 : 0;
282
- tr = ( ((parity_clip ^ ((horiz_clip!=HState.NH)?1:0)) !=0) &&
283
- ((parity_subj ^ ((horiz_subj!=HState.NH)?1:0)) !=0) ) ? 1 : 0;
284
- tl = (((parity_clip ^ ((horiz_clip!=HState.NH)?1:0) ^ edge.bundle_below_clip)!=0) &&
285
- ((parity_subj ^ ((horiz_subj!=HState.NH)?1:0) ^ edge.bundle_below_subj)!=0))?1:0;
286
- }
287
- else if( op == OperationType.GPC_XOR )
288
- {
289
- contributing= (exists_clip!=0) || (exists_subj!=0);
290
- br= (parity_clip) ^ (parity_subj);
291
- bl= (parity_clip ^ edge.bundle_above[CLIP]) ^ (parity_subj ^ edge.bundle_above[SUBJ]);
292
- tr= (parity_clip ^ ((horiz_clip!=HState.NH)?1:0)) ^ (parity_subj ^ ((horiz_subj!=HState.NH)?1:0));
293
- tl= (parity_clip ^ ((horiz_clip!=HState.NH)?1:0) ^ edge.bundle_below_clip)
294
- ^ (parity_subj ^ ((horiz_subj!=HState.NH)?1:0) ^ edge.bundle_below_subj);
295
- }
296
- else if( op == OperationType.GPC_UNION )
297
- {
298
- contributing= ((exists_clip!=0) && (!(parity_subj!=0) || (horiz_subj!=0))) ||
299
- ((exists_subj!=0) && (!(parity_clip!=0) || (horiz_clip!=0))) ||
300
- ((exists_clip!=0) && (exists_subj!=0) && (parity_clip == parity_subj));
301
- br= ((parity_clip!=0) || (parity_subj!=0))?1:0;
302
- bl= (((parity_clip ^ edge.bundle_above[CLIP])!=0) || ((parity_subj ^ edge.bundle_above[SUBJ])!=0))?1:0;
303
- tr= ( ((parity_clip ^ ((horiz_clip!=HState.NH)?1:0))!=0) ||
304
- ((parity_subj ^ ((horiz_subj!=HState.NH)?1:0))!=0) ) ?1:0;
305
- tl= ( ((parity_clip ^ ((horiz_clip!=HState.NH)?1:0) ^ edge.bundle_below_clip)!=0) ||
306
- ((parity_subj ^ ((horiz_subj!=HState.NH)?1:0) ^ edge.bundle_below_subj)!=0) ) ? 1:0;
307
- }
308
- else
309
- {
310
- throw new IllegalStateException("Unknown op");
311
- }
312
-
313
- /* Update parity */
314
- parity_clip ^= edge.bundle_above[CLIP];
315
- parity_subj ^= edge.bundle_above[SUBJ];
316
-
317
- /* Update horizontal state */
318
- if (exists_clip!=0)
319
- {
320
- horiz_clip = HState.next_h_state[horiz_clip][((exists_clip - 1) << 1) + parity_clip];
321
- }
322
- if( exists_subj!=0)
323
- {
324
- horiz_subj = HState.next_h_state[horiz_subj][((exists_subj - 1) << 1) + parity_subj];
325
- }
326
-
327
- if (contributing) // DIFFERENT!
328
- {
329
- float xb = edge.xb;
330
-
331
- int vclass = VertexType.getType( tr, tl, br, bl );
332
- switch (vclass)
333
- {
334
- case VertexType.EMN:
335
- case VertexType.IMN:
336
- edge.outp_above = out_poly.add_local_min(xb, yb);
337
- px = xb;
338
- cf = edge.outp_above;
339
- break;
340
- case VertexType.ERI:
341
- if (xb != px)
342
- {
343
- cf.add_right( xb, yb);
344
- px= xb;
345
- }
346
- edge.outp_above= cf;
347
- cf= null;
348
- break;
349
- case VertexType.ELI:
350
- edge.outp_below.add_left( xb, yb);
351
- px= xb;
352
- cf= edge.outp_below;
353
- break;
354
- case VertexType.EMX:
355
- if (xb != px)
356
- {
357
- cf.add_left( xb, yb);
358
- px= xb;
359
- }
360
- out_poly.merge_right(cf, edge.outp_below);
361
- cf= null;
362
- break;
363
- case VertexType.ILI:
364
- if (xb != px)
365
- {
366
- cf.add_left( xb, yb);
367
- px= xb;
368
- }
369
- edge.outp_above= cf;
370
- cf= null;
371
- break;
372
- case VertexType.IRI:
373
- edge.outp_below.add_right( xb, yb );
374
- px= xb;
375
- cf= edge.outp_below;
376
- edge.outp_below= null;
377
- break;
378
- case VertexType.IMX:
379
- if (xb != px)
380
- {
381
- cf.add_right( xb, yb );
382
- px= xb;
383
- }
384
- out_poly.merge_left(cf, edge.outp_below);
385
- cf= null;
386
- edge.outp_below= null;
387
- break;
388
- case VertexType.IMM:
389
- if (xb != px)
390
- {
391
- cf.add_right( xb, yb);
392
- px= xb;
393
- }
394
- out_poly.merge_left(cf, edge.outp_below);
395
- edge.outp_below= null;
396
- edge.outp_above = out_poly.add_local_min(xb, yb);
397
- cf= edge.outp_above;
398
- break;
399
- case VertexType.EMM:
400
- if (xb != px)
401
- {
402
- cf.add_left( xb, yb);
403
- px= xb;
404
- }
405
- out_poly.merge_right(cf, edge.outp_below);
406
- edge.outp_below= null;
407
- edge.outp_above = out_poly.add_local_min(xb, yb);
408
- cf= edge.outp_above;
409
- break;
410
- case VertexType.LED:
411
- if (edge.bot_y == yb)
412
- edge.outp_below.add_left( xb, yb);
413
- edge.outp_above= edge.outp_below;
414
- px= xb;
415
- break;
416
- case VertexType.RED:
417
- if (edge.bot_y == yb)
418
- edge.outp_below.add_right( xb, yb );
419
- edge.outp_above= edge.outp_below;
420
- px= xb;
421
- break;
422
- default:
423
- break;
424
- } /* End of switch */
425
- } /* End of contributing conditional */
426
- } /* End of edge exists conditional */
427
- } /* End of AET loop */
428
-
429
- /* Delete terminating edges from the AET, otherwise compute xt */
430
- for (EdgeNode edge = aet.top_node; (edge != null); edge = edge.next)
284
+
285
+ /* Update parity */
286
+ parity_clip ^= edge.bundle_above[CLIP];
287
+ parity_subj ^= edge.bundle_above[SUBJ];
288
+
289
+ /* Update horizontal state */
290
+ if (exists_clip != 0) {
291
+ horiz_clip = HState.NEXT_H_STATE[horiz_clip][((exists_clip - 1) << 1) + parity_clip];
292
+ }
293
+ if (exists_subj != 0) {
294
+ horiz_subj = HState.NEXT_H_STATE[horiz_subj][((exists_subj - 1) << 1) + parity_subj];
295
+ }
296
+
297
+ if (contributing) // DIFFERENT!
431
298
  {
432
- if (edge.top_y == yb)
433
- {
434
- EdgeNode prev_edge = edge.prev;
435
- EdgeNode next_edge = edge.next;
436
-
437
- if (prev_edge != null)
438
- prev_edge.next = next_edge;
439
- else
440
- aet.top_node = next_edge;
441
-
442
- if (next_edge != null )
443
- next_edge.prev = prev_edge;
444
-
445
- /* Copy bundle head state to the adjacent tail edge if required */
446
- if ((edge.bstate_below == BundleState.BUNDLE_HEAD) && (prev_edge!=null))
447
- {
448
- if (prev_edge.bstate_below == BundleState.BUNDLE_TAIL)
449
- {
450
- prev_edge.outp_below= edge.outp_below;
451
- prev_edge.bstate_below= BundleState.UNBUNDLED;
452
- if ( prev_edge.prev != null)
453
- {
454
- if (prev_edge.prev.bstate_below == BundleState.BUNDLE_TAIL)
455
- {
456
- prev_edge.bstate_below = BundleState.BUNDLE_HEAD;
457
- }
458
- }
459
- }
460
- }
461
- }
462
- else
463
- {
464
- if (edge.top_y == yt)
465
- edge.xt= edge.top_x;
466
- else
467
- edge.xt= edge.bot_x + edge.dx * (yt - edge.bot_y);
299
+ float xb = edge.xb;
300
+
301
+ int vclass = VertexType.getType(tr, tl, br, bl);
302
+ switch (vclass) {
303
+ case VertexType.EMN:
304
+ case VertexType.IMN:
305
+ edge.outp_above = out_poly.add_local_min(xb, yb);
306
+ px = xb;
307
+ cf = edge.outp_above;
308
+ break;
309
+ case VertexType.ERI:
310
+ if (xb != px) {
311
+ cf.add_right(xb, yb);
312
+ px = xb;
313
+ }
314
+ edge.outp_above = cf;
315
+ cf = null;
316
+ break;
317
+ case VertexType.ELI:
318
+ edge.outp_below.add_left(xb, yb);
319
+ px = xb;
320
+ cf = edge.outp_below;
321
+ break;
322
+ case VertexType.EMX:
323
+ if (xb != px) {
324
+ cf.add_left(xb, yb);
325
+ px = xb;
326
+ }
327
+ out_poly.merge_right(cf, edge.outp_below);
328
+ cf = null;
329
+ break;
330
+ case VertexType.ILI:
331
+ if (xb != px) {
332
+ cf.add_left(xb, yb);
333
+ px = xb;
334
+ }
335
+ edge.outp_above = cf;
336
+ cf = null;
337
+ break;
338
+ case VertexType.IRI:
339
+ edge.outp_below.add_right(xb, yb);
340
+ px = xb;
341
+ cf = edge.outp_below;
342
+ edge.outp_below = null;
343
+ break;
344
+ case VertexType.IMX:
345
+ if (xb != px) {
346
+ cf.add_right(xb, yb);
347
+ px = xb;
348
+ }
349
+ out_poly.merge_left(cf, edge.outp_below);
350
+ cf = null;
351
+ edge.outp_below = null;
352
+ break;
353
+ case VertexType.IMM:
354
+ if (xb != px) {
355
+ cf.add_right(xb, yb);
356
+ px = xb;
357
+ }
358
+ out_poly.merge_left(cf, edge.outp_below);
359
+ edge.outp_below = null;
360
+ edge.outp_above = out_poly.add_local_min(xb, yb);
361
+ cf = edge.outp_above;
362
+ break;
363
+ case VertexType.EMM:
364
+ if (xb != px) {
365
+ cf.add_left(xb, yb);
366
+ px = xb;
367
+ }
368
+ out_poly.merge_right(cf, edge.outp_below);
369
+ edge.outp_below = null;
370
+ edge.outp_above = out_poly.add_local_min(xb, yb);
371
+ cf = edge.outp_above;
372
+ break;
373
+ case VertexType.LED:
374
+ if (edge.bot_y == yb) {
375
+ edge.outp_below.add_left(xb, yb);
376
+ }
377
+ edge.outp_above = edge.outp_below;
378
+ px = xb;
379
+ break;
380
+ case VertexType.RED:
381
+ if (edge.bot_y == yb) {
382
+ edge.outp_below.add_right(xb, yb);
383
+ }
384
+ edge.outp_above = edge.outp_below;
385
+ px = xb;
386
+ break;
387
+ default:
388
+ break;
389
+ }
390
+ /* End of switch */
391
+ }
392
+ /* End of contributing conditional */
393
+ }
394
+ /* End of edge exists conditional */
395
+ }
396
+ /* End of AET loop */
397
+
398
+ /* Delete terminating edges from the AET, otherwise compute xt */
399
+ for (EdgeNode edge = aet.top_node; (edge != null); edge = edge.next) {
400
+ if (edge.top_y == yb) {
401
+ EdgeNode prev_edge = edge.prev;
402
+ EdgeNode next_edge = edge.next;
403
+
404
+ if (prev_edge != null) {
405
+ prev_edge.next = next_edge;
406
+ } else {
407
+ aet.top_node = next_edge;
408
+ }
409
+
410
+ if (next_edge != null) {
411
+ next_edge.prev = prev_edge;
412
+ }
413
+
414
+ /* Copy bundle head state to the adjacent tail edge if required */
415
+ if ((edge.bstate_below == BundleState.BUNDLE_HEAD) && (prev_edge != null)) {
416
+ if (prev_edge.bstate_below == BundleState.BUNDLE_TAIL) {
417
+ prev_edge.outp_below = edge.outp_below;
418
+ prev_edge.bstate_below = BundleState.UNBUNDLED;
419
+ if (prev_edge.prev != null) {
420
+ if (prev_edge.prev.bstate_below == BundleState.BUNDLE_TAIL) {
421
+ prev_edge.bstate_below = BundleState.BUNDLE_HEAD;
422
+ }
468
423
  }
424
+ }
469
425
  }
470
-
471
- if (scanbeam < sbte.sbt_entries )
472
- {
473
- /* === SCANBEAM INTERIOR PROCESSING ============================== */
474
-
475
- /* Build intersection table for the current scanbeam */
476
- ItNodeTable it_table = new ItNodeTable();
477
- it_table.build_intersection_table(aet, dy);
478
-
479
- /* Process each node in the intersection table */
480
- for (ItNode intersect = it_table.top_node; (intersect != null); intersect = intersect.next)
481
- {
482
- e0= intersect.ie0;
483
- e1= intersect.ie1;
484
-
485
- /* Only generate output for contributing intersections */
486
- if ( ((e0.bundle_above[CLIP]!=0) || (e0.bundle_above[SUBJ]!=0)) &&
487
- ((e1.bundle_above[CLIP]!=0) || (e1.bundle_above[SUBJ]!=0)))
488
- {
489
- PolygonNode p = e0.outp_above;
490
- PolygonNode q = e1.outp_above;
491
- float ix = intersect.point_x;
492
- float iy = intersect.point_y + yb;
493
-
494
- int in_clip = ( ( (e0.bundle_above[CLIP]!=0) && !(e0.bside_clip!=0)) ||
495
- ( (e1.bundle_above[CLIP]!=0) && (e1.bside_clip!=0)) ||
496
- (!(e0.bundle_above[CLIP]!=0) && !(e1.bundle_above[CLIP]!=0) &&
497
- (e0.bside_clip!=0) && (e1.bside_clip!=0) ) ) ? 1 : 0;
498
-
499
- int in_subj = ( ( (e0.bundle_above[SUBJ]!=0) && !(e0.bside_subj!=0)) ||
500
- ( (e1.bundle_above[SUBJ]!=0) && (e1.bside_subj!=0)) ||
501
- (!(e0.bundle_above[SUBJ]!=0) && !(e1.bundle_above[SUBJ]!=0) &&
502
- (e0.bside_subj!=0) && (e1.bside_subj!=0) ) ) ? 1 : 0;
503
-
504
- int tr=0, tl=0, br=0, bl=0;
505
- /* Determine quadrant occupancies */
506
- if( (op == OperationType.GPC_DIFF) || (op == OperationType.GPC_INT) )
507
- {
508
- tr= ((in_clip!=0) && (in_subj!=0)) ? 1 : 0;
509
- tl= (((in_clip ^ e1.bundle_above[CLIP])!=0) && ((in_subj ^ e1.bundle_above[SUBJ])!=0))?1:0;
510
- br= (((in_clip ^ e0.bundle_above[CLIP])!=0) && ((in_subj ^ e0.bundle_above[SUBJ])!=0))?1:0;
511
- bl= (((in_clip ^ e1.bundle_above[CLIP] ^ e0.bundle_above[CLIP])!=0) &&
512
- ((in_subj ^ e1.bundle_above[SUBJ] ^ e0.bundle_above[SUBJ])!=0) ) ? 1:0;
513
- }
514
- else if( op == OperationType.GPC_XOR )
515
- {
516
- tr= (in_clip)^ (in_subj);
517
- tl= (in_clip ^ e1.bundle_above[CLIP]) ^ (in_subj ^ e1.bundle_above[SUBJ]);
518
- br= (in_clip ^ e0.bundle_above[CLIP]) ^ (in_subj ^ e0.bundle_above[SUBJ]);
519
- bl= (in_clip ^ e1.bundle_above[CLIP] ^ e0.bundle_above[CLIP])
520
- ^ (in_subj ^ e1.bundle_above[SUBJ] ^ e0.bundle_above[SUBJ]);
521
- }
522
- else if( op == OperationType.GPC_UNION )
523
- {
524
- tr= ((in_clip!=0) || (in_subj!=0)) ? 1 : 0;
525
- tl= (((in_clip ^ e1.bundle_above[CLIP])!=0) || ((in_subj ^ e1.bundle_above[SUBJ])!=0)) ? 1 : 0;
526
- br= (((in_clip ^ e0.bundle_above[CLIP])!=0) || ((in_subj ^ e0.bundle_above[SUBJ])!=0)) ? 1 : 0;
527
- bl= (((in_clip ^ e1.bundle_above[CLIP] ^ e0.bundle_above[CLIP])!=0) ||
528
- ((in_subj ^ e1.bundle_above[SUBJ] ^ e0.bundle_above[SUBJ])!=0)) ? 1 : 0;
529
- }
530
- else
531
- {
532
- throw new IllegalStateException("Unknown op type, "+op);
533
- }
534
-
535
- int vclass = VertexType.getType( tr, tl, br, bl );
536
- switch (vclass)
537
- {
538
- case VertexType.EMN:
539
- e0.outp_above = out_poly.add_local_min(ix, iy);
540
- e1.outp_above = e0.outp_above;
541
- break;
542
- case VertexType.ERI:
543
- if (p != null)
544
- {
545
- p.add_right(ix, iy);
546
- e1.outp_above= p;
547
- e0.outp_above= null;
548
- }
549
- break;
550
- case VertexType.ELI:
551
- if (q != null)
552
- {
553
- q.add_left(ix, iy);
554
- e0.outp_above= q;
555
- e1.outp_above= null;
556
- }
557
- break;
558
- case VertexType.EMX:
559
- if ((p!=null) && (q!=null))
560
- {
561
- p.add_left( ix, iy);
562
- out_poly.merge_right(p, q);
563
- e0.outp_above= null;
564
- e1.outp_above= null;
565
- }
566
- break;
567
- case VertexType.IMN:
568
- e0.outp_above = out_poly.add_local_min(ix, iy);
569
- e1.outp_above= e0.outp_above;
570
- break;
571
- case VertexType.ILI:
572
- if (p != null)
573
- {
574
- p.add_left(ix, iy);
575
- e1.outp_above= p;
576
- e0.outp_above= null;
577
- }
578
- break;
579
- case VertexType.IRI:
580
- if (q!=null)
581
- {
582
- q.add_right(ix, iy);
583
- e0.outp_above= q;
584
- e1.outp_above= null;
585
- }
586
- break;
587
- case VertexType.IMX:
588
- if ((p!=null) && (q!=null))
589
- {
590
- p.add_right(ix, iy);
591
- out_poly.merge_left(p, q);
592
- e0.outp_above= null;
593
- e1.outp_above= null;
594
- }
595
- break;
596
- case VertexType.IMM:
597
- if ((p!=null) && (q!=null))
598
- {
599
- p.add_right(ix, iy);
600
- out_poly.merge_left(p, q);
601
- e0.outp_above = out_poly.add_local_min(ix, iy);
602
- e1.outp_above= e0.outp_above;
603
- }
604
- break;
605
- case VertexType.EMM:
606
- if ((p!=null) && (q!=null))
607
- {
608
- p.add_left(ix, iy);
609
- out_poly.merge_right(p, q);
610
- e0.outp_above = out_poly.add_local_min(ix, iy);
611
- e1.outp_above = e0.outp_above;
612
- }
613
- break;
614
- default:
615
- break;
616
- } /* End of switch */
617
- } /* End of contributing intersection conditional */
618
-
619
- /* Swap bundle sides in response to edge crossing */
620
- if (e0.bundle_above[CLIP]!=0)
621
- e1.bside_clip = (e1.bside_clip==0)?1:0;
622
- if (e1.bundle_above[CLIP]!=0)
623
- e0.bside_clip= (e0.bside_clip==0)?1:0;
624
- if (e0.bundle_above[SUBJ]!=0)
625
- e1.bside_subj= (e1.bside_subj==0)?1:0;
626
- if (e1.bundle_above[SUBJ]!=0)
627
- e0.bside_subj= (e0.bside_subj==0)?1:0;
628
-
629
- /* Swap e0 and e1 bundles in the AET */
630
- EdgeNode prev_edge = e0.prev;
631
- EdgeNode next_edge = e1.next;
632
- if (next_edge != null)
633
- {
634
- next_edge.prev = e0;
635
- }
636
-
637
- if (e0.bstate_above == BundleState.BUNDLE_HEAD)
638
- {
639
- boolean search = true;
640
- while (search)
641
- {
642
- prev_edge = prev_edge.prev;
643
- if (prev_edge != null)
644
- {
645
- if (prev_edge.bstate_above != BundleState.BUNDLE_TAIL)
646
- {
647
- search= false;
648
- }
649
- }
650
- else
651
- {
652
- search= false;
653
- }
654
- }
655
- }
656
- if (prev_edge == null)
657
- {
658
- aet.top_node.prev = e1;
659
- e1.next = aet.top_node;
660
- aet.top_node = e0.next;
661
- }
662
- else
663
- {
664
- prev_edge.next.prev = e1;
665
- e1.next = prev_edge.next;
666
- prev_edge.next = e0.next;
667
- }
668
- e0.next.prev = prev_edge;
669
- e1.next.prev = e1;
670
- e0.next = next_edge;
671
- } /* End of IT loop*/
672
-
673
- /* Prepare for next scanbeam */
674
- for ( EdgeNode edge = aet.top_node; (edge != null); edge = edge.next)
675
- {
676
- EdgeNode next_edge = edge.next;
677
- EdgeNode succ_edge = edge.succ;
678
- if ((edge.top_y == yt) && (succ_edge!=null))
679
- {
680
- /* Replace AET edge by its successor */
681
- succ_edge.outp_below= edge.outp_above;
682
- succ_edge.bstate_below= edge.bstate_above;
683
- succ_edge.bundle_below_clip= edge.bundle_above[CLIP];
684
- succ_edge.bundle_below_subj= edge.bundle_above[SUBJ];
685
- EdgeNode prev_edge = edge.prev;
686
- if ( prev_edge != null )
687
- prev_edge.next = succ_edge;
688
- else
689
- aet.top_node = succ_edge;
690
- if (next_edge != null)
691
- next_edge.prev= succ_edge;
692
- succ_edge.prev = prev_edge;
693
- succ_edge.next = next_edge;
694
- }
695
- else
696
- {
697
- /* Update this edge */
698
- edge.outp_below= edge.outp_above;
699
- edge.bstate_below= edge.bstate_above;
700
- edge.bundle_below_clip= edge.bundle_above[CLIP];
701
- edge.bundle_below_subj= edge.bundle_above[SUBJ];
702
- edge.xb= edge.xt;
703
- }
704
- edge.outp_above= null;
426
+ } else {
427
+ if (edge.top_y == yt) {
428
+ edge.xt = edge.top_x;
429
+ } else {
430
+ edge.xt = edge.bot_x + edge.dx * (yt - edge.bot_y);
431
+ }
432
+ }
433
+ }
434
+
435
+ if (scanbeam < sbte.sbt_entries) {
436
+ /* === SCANBEAM INTERIOR PROCESSING ============================== */
437
+
438
+ /* Build intersection table for the current scanbeam */
439
+ ItNodeTable it_table = new ItNodeTable();
440
+ it_table.build_intersection_table(aet, dy);
441
+
442
+ /* Process each node in the intersection table */
443
+ for (ItNode intersect = it_table.top_node; (intersect != null); intersect = intersect.next) {
444
+ e0 = intersect.ie0;
445
+ e1 = intersect.ie1;
446
+
447
+ /* Only generate output for contributing intersections */
448
+ if (((e0.bundle_above[CLIP] != 0) || (e0.bundle_above[SUBJ] != 0))
449
+ && ((e1.bundle_above[CLIP] != 0) || (e1.bundle_above[SUBJ] != 0))) {
450
+ PolygonNode p = e0.outp_above;
451
+ PolygonNode q = e1.outp_above;
452
+ float ix = intersect.point_x;
453
+ float iy = intersect.point_y + yb;
454
+
455
+ int in_clip = (((e0.bundle_above[CLIP] != 0) && !(e0.bside_clip != 0))
456
+ || ((e1.bundle_above[CLIP] != 0) && (e1.bside_clip != 0))
457
+ || (!(e0.bundle_above[CLIP] != 0) && !(e1.bundle_above[CLIP] != 0)
458
+ && (e0.bside_clip != 0) && (e1.bside_clip != 0))) ? 1 : 0;
459
+
460
+ int in_subj = (((e0.bundle_above[SUBJ] != 0) && !(e0.bside_subj != 0))
461
+ || ((e1.bundle_above[SUBJ] != 0) && (e1.bside_subj != 0))
462
+ || (!(e0.bundle_above[SUBJ] != 0) && !(e1.bundle_above[SUBJ] != 0)
463
+ && (e0.bside_subj != 0) && (e1.bside_subj != 0))) ? 1 : 0;
464
+
465
+ int tr = 0, tl = 0, br = 0, bl = 0;
466
+ /* Determine quadrant occupancies */
467
+ if ((op == OperationType.GPC_DIFF) || (op == OperationType.GPC_INT)) {
468
+ tr = ((in_clip != 0) && (in_subj != 0)) ? 1 : 0;
469
+ tl = (((in_clip ^ e1.bundle_above[CLIP]) != 0) && ((in_subj ^ e1.bundle_above[SUBJ]) != 0)) ? 1 : 0;
470
+ br = (((in_clip ^ e0.bundle_above[CLIP]) != 0) && ((in_subj ^ e0.bundle_above[SUBJ]) != 0)) ? 1 : 0;
471
+ bl = (((in_clip ^ e1.bundle_above[CLIP] ^ e0.bundle_above[CLIP]) != 0)
472
+ && ((in_subj ^ e1.bundle_above[SUBJ] ^ e0.bundle_above[SUBJ]) != 0)) ? 1 : 0;
473
+ } else if (op == OperationType.GPC_XOR) {
474
+ tr = (in_clip) ^ (in_subj);
475
+ tl = (in_clip ^ e1.bundle_above[CLIP]) ^ (in_subj ^ e1.bundle_above[SUBJ]);
476
+ br = (in_clip ^ e0.bundle_above[CLIP]) ^ (in_subj ^ e0.bundle_above[SUBJ]);
477
+ bl = (in_clip ^ e1.bundle_above[CLIP] ^ e0.bundle_above[CLIP])
478
+ ^ (in_subj ^ e1.bundle_above[SUBJ] ^ e0.bundle_above[SUBJ]);
479
+ } else if (op == OperationType.GPC_UNION) {
480
+ tr = ((in_clip != 0) || (in_subj != 0)) ? 1 : 0;
481
+ tl = (((in_clip ^ e1.bundle_above[CLIP]) != 0) || ((in_subj ^ e1.bundle_above[SUBJ]) != 0)) ? 1 : 0;
482
+ br = (((in_clip ^ e0.bundle_above[CLIP]) != 0) || ((in_subj ^ e0.bundle_above[SUBJ]) != 0)) ? 1 : 0;
483
+ bl = (((in_clip ^ e1.bundle_above[CLIP] ^ e0.bundle_above[CLIP]) != 0)
484
+ || ((in_subj ^ e1.bundle_above[SUBJ] ^ e0.bundle_above[SUBJ]) != 0)) ? 1 : 0;
485
+ } else {
486
+ throw new IllegalStateException("Unknown op type, " + op);
487
+ }
488
+
489
+ int vclass = VertexType.getType(tr, tl, br, bl);
490
+ switch (vclass) {
491
+ case VertexType.EMN:
492
+ e0.outp_above = out_poly.add_local_min(ix, iy);
493
+ e1.outp_above = e0.outp_above;
494
+ break;
495
+ case VertexType.ERI:
496
+ if (p != null) {
497
+ p.add_right(ix, iy);
498
+ e1.outp_above = p;
499
+ e0.outp_above = null;
500
+ }
501
+ break;
502
+ case VertexType.ELI:
503
+ if (q != null) {
504
+ q.add_left(ix, iy);
505
+ e0.outp_above = q;
506
+ e1.outp_above = null;
507
+ }
508
+ break;
509
+ case VertexType.EMX:
510
+ if ((p != null) && (q != null)) {
511
+ p.add_left(ix, iy);
512
+ out_poly.merge_right(p, q);
513
+ e0.outp_above = null;
514
+ e1.outp_above = null;
515
+ }
516
+ break;
517
+ case VertexType.IMN:
518
+ e0.outp_above = out_poly.add_local_min(ix, iy);
519
+ e1.outp_above = e0.outp_above;
520
+ break;
521
+ case VertexType.ILI:
522
+ if (p != null) {
523
+ p.add_left(ix, iy);
524
+ e1.outp_above = p;
525
+ e0.outp_above = null;
526
+ }
527
+ break;
528
+ case VertexType.IRI:
529
+ if (q != null) {
530
+ q.add_right(ix, iy);
531
+ e0.outp_above = q;
532
+ e1.outp_above = null;
533
+ }
534
+ break;
535
+ case VertexType.IMX:
536
+ if ((p != null) && (q != null)) {
537
+ p.add_right(ix, iy);
538
+ out_poly.merge_left(p, q);
539
+ e0.outp_above = null;
540
+ e1.outp_above = null;
541
+ }
542
+ break;
543
+ case VertexType.IMM:
544
+ if ((p != null) && (q != null)) {
545
+ p.add_right(ix, iy);
546
+ out_poly.merge_left(p, q);
547
+ e0.outp_above = out_poly.add_local_min(ix, iy);
548
+ e1.outp_above = e0.outp_above;
549
+ }
550
+ break;
551
+ case VertexType.EMM:
552
+ if ((p != null) && (q != null)) {
553
+ p.add_left(ix, iy);
554
+ out_poly.merge_right(p, q);
555
+ e0.outp_above = out_poly.add_local_min(ix, iy);
556
+ e1.outp_above = e0.outp_above;
557
+ }
558
+ break;
559
+ default:
560
+ break;
561
+ }
562
+ /* End of switch */
563
+ }
564
+ /* End of contributing intersection conditional */
565
+
566
+ /* Swap bundle sides in response to edge crossing */
567
+ if (e0.bundle_above[CLIP] != 0) {
568
+ e1.bside_clip = (e1.bside_clip == 0) ? 1 : 0;
569
+ }
570
+ if (e1.bundle_above[CLIP] != 0) {
571
+ e0.bside_clip = (e0.bside_clip == 0) ? 1 : 0;
572
+ }
573
+ if (e0.bundle_above[SUBJ] != 0) {
574
+ e1.bside_subj = (e1.bside_subj == 0) ? 1 : 0;
575
+ }
576
+ if (e1.bundle_above[SUBJ] != 0) {
577
+ e0.bside_subj = (e0.bside_subj == 0) ? 1 : 0;
578
+ }
579
+
580
+ /* Swap e0 and e1 bundles in the AET */
581
+ EdgeNode prev_edge = e0.prev;
582
+ EdgeNode next_edge = e1.next;
583
+ if (next_edge != null) {
584
+ next_edge.prev = e0;
585
+ }
586
+
587
+ if (e0.bstate_above == BundleState.BUNDLE_HEAD) {
588
+ boolean search = true;
589
+ while (search) {
590
+ prev_edge = prev_edge.prev;
591
+ if (prev_edge != null) {
592
+ if (prev_edge.bstate_above != BundleState.BUNDLE_TAIL) {
593
+ search = false;
594
+ }
595
+ } else {
596
+ search = false;
705
597
  }
598
+ }
706
599
  }
707
- } /* === END OF SCANBEAM PROCESSING ================================== */
708
-
709
- /* Generate result polygon from out_poly */
600
+ if (prev_edge == null) {
601
+ aet.top_node.prev = e1;
602
+ e1.next = aet.top_node;
603
+ aet.top_node = e0.next;
604
+ } else {
605
+ prev_edge.next.prev = e1;
606
+ e1.next = prev_edge.next;
607
+ prev_edge.next = e0.next;
608
+ }
609
+ e0.next.prev = prev_edge;
610
+ e1.next.prev = e1;
611
+ e0.next = next_edge;
612
+ }
613
+ /* End of IT loop*/
614
+
615
+ /* Prepare for next scanbeam */
616
+ for (EdgeNode edge = aet.top_node; (edge != null); edge = edge.next) {
617
+ EdgeNode next_edge = edge.next;
618
+ EdgeNode succ_edge = edge.succ;
619
+ if ((edge.top_y == yt) && (succ_edge != null)) {
620
+ /* Replace AET edge by its successor */
621
+ succ_edge.outp_below = edge.outp_above;
622
+ succ_edge.bstate_below = edge.bstate_above;
623
+ succ_edge.bundle_below_clip = edge.bundle_above[CLIP];
624
+ succ_edge.bundle_below_subj = edge.bundle_above[SUBJ];
625
+ EdgeNode prev_edge = edge.prev;
626
+ if (prev_edge != null) {
627
+ prev_edge.next = succ_edge;
628
+ } else {
629
+ aet.top_node = succ_edge;
630
+ }
631
+ if (next_edge != null) {
632
+ next_edge.prev = succ_edge;
633
+ }
634
+ succ_edge.prev = prev_edge;
635
+ succ_edge.next = next_edge;
636
+ } else {
637
+ /* Update this edge */
638
+ edge.outp_below = edge.outp_above;
639
+ edge.bstate_below = edge.bstate_above;
640
+ edge.bundle_below_clip = edge.bundle_above[CLIP];
641
+ edge.bundle_below_subj = edge.bundle_above[SUBJ];
642
+ edge.xb = edge.xt;
643
+ }
644
+ edge.outp_above = null;
645
+ }
646
+ }
647
+ }
648
+ /* === END OF SCANBEAM PROCESSING ================================== */
649
+
650
+ /* Generate result polygon from out_poly */
710
651
  result = out_poly.getResult(polyClass);
711
-
652
+
712
653
  return result;
713
654
  }
714
-
655
+
715
656
  /**
716
657
  * Clipper to output tristrips
717
658
  */
718
- static RMesh clip( OperationType op, RPolygon subj, RPolygon clip )
719
- {
659
+ static RMesh clip(OperationType op, RPolygon subj, RPolygon clip) {
720
660
  PolygonNode tlist = null;
721
661
  float nx = 0;
722
-
662
+
723
663
  /* Test for trivial NULL result cases */
724
- if( (subj.isEmpty() && clip.isEmpty()) ||
725
- (subj.isEmpty() && ((op == OperationType.GPC_INT) || (op == OperationType.GPC_DIFF))) ||
726
- (clip.isEmpty() && (op == OperationType.GPC_INT)) )
727
- {
728
- return null;
729
- }
730
-
664
+ if ((subj.isEmpty() && clip.isEmpty())
665
+ || (subj.isEmpty() && ((op == OperationType.GPC_INT) || (op == OperationType.GPC_DIFF)))
666
+ || (clip.isEmpty() && (op == OperationType.GPC_INT))) {
667
+ return null;
668
+ }
669
+
731
670
  /* Identify potentialy contributing contours */
732
- if( ((op == OperationType.GPC_INT) || (op == OperationType.GPC_DIFF)) &&
733
- !subj.isEmpty() && !clip.isEmpty() )
734
- {
735
- minimax_test(subj, clip, op);
736
- }
737
-
671
+ if (((op == OperationType.GPC_INT) || (op == OperationType.GPC_DIFF))
672
+ && !subj.isEmpty() && !clip.isEmpty()) {
673
+ minimax_test(subj, clip, op);
674
+ }
675
+
738
676
  /* Build LMT */
739
677
  LmtTable lmt_table = new LmtTable();
740
678
  ScanBeamTreeEntries sbte = new ScanBeamTreeEntries();
741
- if (!subj.isEmpty())
742
- {
743
- build_lmt(lmt_table, sbte, subj, SUBJ, op);
744
- }
745
- if (!clip.isEmpty())
746
- {
747
- build_lmt(lmt_table, sbte, clip, CLIP, op);
748
- }
749
-
679
+ if (!subj.isEmpty()) {
680
+ build_lmt(lmt_table, sbte, subj, SUBJ, op);
681
+ }
682
+ if (!clip.isEmpty()) {
683
+ build_lmt(lmt_table, sbte, clip, CLIP, op);
684
+ }
685
+
750
686
  /* Return a NULL result if no contours contribute */
751
- if (lmt_table.top_node == null)
752
- {
753
- return null;
754
- }
755
-
687
+ if (lmt_table.top_node == null) {
688
+ return null;
689
+ }
690
+
756
691
  /* Build scanbeam table from scanbeam tree */
757
692
  float[] sbt = sbte.build_sbt();
758
-
693
+
759
694
  int parity_clip = LEFT;
760
695
  int parity_subj = LEFT;
761
-
696
+
762
697
  /* Invert clip polygon for difference operation */
763
- if (op == OperationType.GPC_DIFF)
764
- {
765
- parity_clip= RIGHT;
766
- }
767
-
698
+ if (op == OperationType.GPC_DIFF) {
699
+ parity_clip = RIGHT;
700
+ }
701
+
768
702
  LmtNode local_min = lmt_table.top_node;
769
-
703
+
770
704
  AetTree aet = new AetTree();
771
705
  int scanbeam = 0;
772
-
706
+
773
707
  /* Process each scanbeam */
774
- while( scanbeam < sbt.length )
775
- {
776
- /* Set yb and yt to the bottom and top of the scanbeam */
777
- float yb = sbt[scanbeam++];
778
- float yt = 0.0F;
779
- float dy = 0.0F;
780
- if( scanbeam < sbt.length )
781
- {
782
- yt = sbt[scanbeam];
783
- dy = yt - yb;
708
+ while (scanbeam < sbt.length) {
709
+ /* Set yb and yt to the bottom and top of the scanbeam */
710
+ float yb = sbt[scanbeam++];
711
+ float yt = 0.0F;
712
+ float dy = 0.0F;
713
+ if (scanbeam < sbt.length) {
714
+ yt = sbt[scanbeam];
715
+ dy = yt - yb;
716
+ }
717
+
718
+ /* === SCANBEAM BOUNDARY PROCESSING ================================ */
719
+ /* If LMT node corresponding to yb exists */
720
+ if (local_min != null) {
721
+ if (local_min.y == yb) {
722
+ /* Add edges starting at this local minimum to the AET */
723
+ for (EdgeNode edge = local_min.first_bound; (edge != null); edge = edge.next_bound) {
724
+ add_edge_to_aet(aet, edge);
784
725
  }
785
-
786
- /* === SCANBEAM BOUNDARY PROCESSING ================================ */
787
-
788
- /* If LMT node corresponding to yb exists */
789
- if (local_min != null )
790
- {
791
- if (local_min.y == yb)
792
- {
793
- /* Add edges starting at this local minimum to the AET */
794
- for( EdgeNode edge = local_min.first_bound; (edge != null); edge= edge.next_bound)
795
- {
796
- add_edge_to_aet( aet, edge );
797
- }
798
-
799
- local_min = local_min.next;
800
- }
726
+
727
+ local_min = local_min.next;
728
+ }
729
+ }
730
+
731
+ /* Set dummy previous x value */
732
+ float px = -Float.MAX_VALUE;
733
+
734
+ /* Create bundles within AET */
735
+ EdgeNode e0 = aet.top_node;
736
+ EdgeNode e1 = aet.top_node;
737
+
738
+ /* Set up bundle fields of first edge */
739
+ aet.top_node.bundle_above[aet.top_node.type] = (aet.top_node.top_y != yb) ? 1 : 0;
740
+ aet.top_node.bundle_above[((aet.top_node.type == 0) ? 1 : 0)] = 0;
741
+ aet.top_node.bstate_above = BundleState.UNBUNDLED;
742
+
743
+ for (EdgeNode next_edge = aet.top_node.next; (next_edge != null); next_edge = next_edge.next) {
744
+ int ne_type = next_edge.type;
745
+ int ne_type_opp = ((next_edge.type == 0) ? 1 : 0); //next edge type opposite
746
+
747
+ /* Set up bundle fields of next edge */
748
+ next_edge.bundle_above[ne_type] = (next_edge.top_y != yb) ? 1 : 0;
749
+ next_edge.bundle_above[ne_type_opp] = 0;
750
+ next_edge.bstate_above = BundleState.UNBUNDLED;
751
+
752
+ /* Bundle edges above the scanbeam boundary if they coincide */
753
+ if (next_edge.bundle_above[ne_type] == 1) {
754
+ if (EQ(e0.xb, next_edge.xb) && EQ(e0.dx, next_edge.dx) && (e0.top_y != yb)) {
755
+ next_edge.bundle_above[ne_type] ^= e0.bundle_above[ne_type];
756
+ next_edge.bundle_above[ne_type_opp] = e0.bundle_above[ne_type_opp];
757
+ next_edge.bstate_above = BundleState.BUNDLE_HEAD;
758
+ e0.bundle_above[CLIP] = 0;
759
+ e0.bundle_above[SUBJ] = 0;
760
+ e0.bstate_above = BundleState.BUNDLE_TAIL;
801
761
  }
802
-
803
- /* Set dummy previous x value */
804
- float px = -Float.MAX_VALUE;
805
-
806
- /* Create bundles within AET */
807
- EdgeNode e0 = aet.top_node;
808
- EdgeNode e1 = aet.top_node;
809
-
810
- /* Set up bundle fields of first edge */
811
- aet.top_node.bundle_above[ aet.top_node.type ] = (aet.top_node.top_y != yb) ? 1 : 0;
812
- aet.top_node.bundle_above[ ((aet.top_node.type==0) ? 1 : 0) ] = 0;
813
- aet.top_node.bstate_above = BundleState.UNBUNDLED;
814
-
815
- for ( EdgeNode next_edge = aet.top_node.next; (next_edge != null); next_edge = next_edge.next)
816
- {
817
- int ne_type = next_edge.type;
818
- int ne_type_opp = ((next_edge.type==0) ? 1 : 0); //next edge type opposite
819
-
820
- /* Set up bundle fields of next edge */
821
- next_edge.bundle_above[ ne_type ]= (next_edge.top_y != yb) ? 1 : 0;
822
- next_edge.bundle_above[ ne_type_opp ] = 0;
823
- next_edge.bstate_above = BundleState.UNBUNDLED;
824
-
825
- /* Bundle edges above the scanbeam boundary if they coincide */
826
- if ( next_edge.bundle_above[ne_type] == 1 )
827
- {
828
- if (EQ(e0.xb, next_edge.xb) && EQ(e0.dx, next_edge.dx) && (e0.top_y != yb))
829
- {
830
- next_edge.bundle_above[ ne_type ] ^= e0.bundle_above[ ne_type ];
831
- next_edge.bundle_above[ ne_type_opp ] = e0.bundle_above[ ne_type_opp ];
832
- next_edge.bstate_above = BundleState.BUNDLE_HEAD;
833
- e0.bundle_above[CLIP] = 0;
834
- e0.bundle_above[SUBJ] = 0;
835
- e0.bstate_above = BundleState.BUNDLE_TAIL;
836
- }
837
- e0 = next_edge;
838
- }
762
+ e0 = next_edge;
763
+ }
764
+ }
765
+
766
+ int horiz_clip = HState.NH;
767
+ int horiz_subj = HState.NH;
768
+
769
+ int exists_clip = 0;
770
+ int exists_subj = 0;
771
+
772
+ EdgeNode cf = null;
773
+ int cft = VertexType.LED;
774
+
775
+ /* Process each edge at this scanbeam boundary */
776
+ for (EdgeNode edge = aet.top_node; (edge != null); edge = edge.next) {
777
+ exists_clip = edge.bundle_above[CLIP] + (edge.bundle_below_clip << 1);
778
+ exists_subj = edge.bundle_above[SUBJ] + (edge.bundle_below_subj << 1);
779
+
780
+ if ((exists_clip != 0) || (exists_subj != 0)) {
781
+ /* Set bundle side */
782
+ edge.bside_clip = parity_clip;
783
+ edge.bside_subj = parity_subj;
784
+
785
+ boolean contributing = false;
786
+ int br = 0, bl = 0, tr = 0, tl = 0;
787
+ /* Determine contributing status and quadrant occupancies */
788
+ if ((op == OperationType.GPC_DIFF) || (op == OperationType.GPC_INT)) {
789
+ contributing = ((exists_clip != 0) && ((parity_subj != 0) || (horiz_subj != 0)))
790
+ || ((exists_subj != 0) && ((parity_clip != 0) || (horiz_clip != 0)))
791
+ || ((exists_clip != 0) && (exists_subj != 0) && (parity_clip == parity_subj));
792
+ br = ((parity_clip != 0) && (parity_subj != 0)) ? 1 : 0;
793
+ bl = (((parity_clip ^ edge.bundle_above[CLIP]) != 0)
794
+ && ((parity_subj ^ edge.bundle_above[SUBJ]) != 0)) ? 1 : 0;
795
+ tr = (((parity_clip ^ ((horiz_clip != HState.NH) ? 1 : 0)) != 0)
796
+ && ((parity_subj ^ ((horiz_subj != HState.NH) ? 1 : 0)) != 0)) ? 1 : 0;
797
+ tl = (((parity_clip ^ ((horiz_clip != HState.NH) ? 1 : 0) ^ edge.bundle_below_clip) != 0)
798
+ && ((parity_subj ^ ((horiz_subj != HState.NH) ? 1 : 0) ^ edge.bundle_below_subj) != 0)) ? 1 : 0;
799
+ } else if (op == OperationType.GPC_XOR) {
800
+ contributing = (exists_clip != 0) || (exists_subj != 0);
801
+ br = (parity_clip) ^ (parity_subj);
802
+ bl = (parity_clip ^ edge.bundle_above[CLIP]) ^ (parity_subj ^ edge.bundle_above[SUBJ]);
803
+ tr = (parity_clip ^ ((horiz_clip != HState.NH) ? 1 : 0)) ^ (parity_subj ^ ((horiz_subj != HState.NH) ? 1 : 0));
804
+ tl = (parity_clip ^ ((horiz_clip != HState.NH) ? 1 : 0) ^ edge.bundle_below_clip)
805
+ ^ (parity_subj ^ ((horiz_subj != HState.NH) ? 1 : 0) ^ edge.bundle_below_subj);
806
+ } else if (op == OperationType.GPC_UNION) {
807
+ contributing = ((exists_clip != 0) && (!(parity_subj != 0) || (horiz_subj != 0)))
808
+ || ((exists_subj != 0) && (!(parity_clip != 0) || (horiz_clip != 0)))
809
+ || ((exists_clip != 0) && (exists_subj != 0) && (parity_clip == parity_subj));
810
+ br = ((parity_clip != 0) || (parity_subj != 0)) ? 1 : 0;
811
+ bl = (((parity_clip ^ edge.bundle_above[CLIP]) != 0) || ((parity_subj ^ edge.bundle_above[SUBJ]) != 0)) ? 1 : 0;
812
+ tr = (((parity_clip ^ ((horiz_clip != HState.NH) ? 1 : 0)) != 0)
813
+ || ((parity_subj ^ ((horiz_subj != HState.NH) ? 1 : 0)) != 0)) ? 1 : 0;
814
+ tl = (((parity_clip ^ ((horiz_clip != HState.NH) ? 1 : 0) ^ edge.bundle_below_clip) != 0)
815
+ || ((parity_subj ^ ((horiz_subj != HState.NH) ? 1 : 0) ^ edge.bundle_below_subj) != 0)) ? 1 : 0;
816
+ } else {
817
+ throw new IllegalStateException("Unknown op");
818
+ }
819
+
820
+ /* Update parity */
821
+ parity_clip ^= edge.bundle_above[CLIP];
822
+ parity_subj ^= edge.bundle_above[SUBJ];
823
+
824
+ /* Update horizontal state */
825
+ if (exists_clip != 0) {
826
+ horiz_clip = HState.NEXT_H_STATE[horiz_clip][((exists_clip - 1) << 1) + parity_clip];
839
827
  }
840
-
841
- int horiz_clip = HState.NH;
842
- int horiz_subj = HState.NH;
843
-
844
- int exists_clip = 0;
845
- int exists_subj = 0;
846
-
847
-
848
- EdgeNode cf = null;
849
- int cft = VertexType.LED;
850
-
851
- /* Process each edge at this scanbeam boundary */
852
- for ( EdgeNode edge = aet.top_node; (edge != null); edge = edge.next )
828
+ if (exists_subj != 0) {
829
+ horiz_subj = HState.NEXT_H_STATE[horiz_subj][((exists_subj - 1) << 1) + parity_subj];
830
+ }
831
+
832
+ if (contributing) // DIFFERENT!
853
833
  {
854
- exists_clip = edge.bundle_above[CLIP] + (edge.bundle_below_clip << 1);
855
- exists_subj = edge.bundle_above[SUBJ] + (edge.bundle_below_subj << 1);
856
-
857
- if( (exists_clip != 0) || (exists_subj != 0) )
858
- {
859
- /* Set bundle side */
860
- edge.bside_clip = parity_clip;
861
- edge.bside_subj = parity_subj;
862
-
863
- boolean contributing = false;
864
- int br=0, bl=0, tr=0, tl=0;
865
- /* Determine contributing status and quadrant occupancies */
866
- if( (op == OperationType.GPC_DIFF) || (op == OperationType.GPC_INT) )
867
- {
868
- contributing= ((exists_clip!=0) && ((parity_subj!=0) || (horiz_subj!=0))) ||
869
- ((exists_subj!=0) && ((parity_clip!=0) || (horiz_clip!=0))) ||
870
- ((exists_clip!=0) && (exists_subj!=0) && (parity_clip == parity_subj));
871
- br = ((parity_clip!=0) && (parity_subj!=0)) ? 1 : 0;
872
- bl = ( ((parity_clip ^ edge.bundle_above[CLIP])!=0) &&
873
- ((parity_subj ^ edge.bundle_above[SUBJ])!=0) ) ? 1 : 0;
874
- tr = ( ((parity_clip ^ ((horiz_clip!=HState.NH)?1:0)) !=0) &&
875
- ((parity_subj ^ ((horiz_subj!=HState.NH)?1:0)) !=0) ) ? 1 : 0;
876
- tl = (((parity_clip ^ ((horiz_clip!=HState.NH)?1:0) ^ edge.bundle_below_clip)!=0) &&
877
- ((parity_subj ^ ((horiz_subj!=HState.NH)?1:0) ^ edge.bundle_below_subj)!=0))?1:0;
878
- }
879
- else if( op == OperationType.GPC_XOR )
880
- {
881
- contributing= (exists_clip!=0) || (exists_subj!=0);
882
- br= (parity_clip) ^ (parity_subj);
883
- bl= (parity_clip ^ edge.bundle_above[CLIP]) ^ (parity_subj ^ edge.bundle_above[SUBJ]);
884
- tr= (parity_clip ^ ((horiz_clip!=HState.NH)?1:0)) ^ (parity_subj ^ ((horiz_subj!=HState.NH)?1:0));
885
- tl= (parity_clip ^ ((horiz_clip!=HState.NH)?1:0) ^ edge.bundle_below_clip)
886
- ^ (parity_subj ^ ((horiz_subj!=HState.NH)?1:0) ^ edge.bundle_below_subj);
887
- }
888
- else if( op == OperationType.GPC_UNION )
889
- {
890
- contributing= ((exists_clip!=0) && (!(parity_subj!=0) || (horiz_subj!=0))) ||
891
- ((exists_subj!=0) && (!(parity_clip!=0) || (horiz_clip!=0))) ||
892
- ((exists_clip!=0) && (exists_subj!=0) && (parity_clip == parity_subj));
893
- br= ((parity_clip!=0) || (parity_subj!=0))?1:0;
894
- bl= (((parity_clip ^ edge.bundle_above[CLIP])!=0) || ((parity_subj ^ edge.bundle_above[SUBJ])!=0))?1:0;
895
- tr= ( ((parity_clip ^ ((horiz_clip!=HState.NH)?1:0))!=0) ||
896
- ((parity_subj ^ ((horiz_subj!=HState.NH)?1:0))!=0) ) ?1:0;
897
- tl= ( ((parity_clip ^ ((horiz_clip!=HState.NH)?1:0) ^ edge.bundle_below_clip)!=0) ||
898
- ((parity_subj ^ ((horiz_subj!=HState.NH)?1:0) ^ edge.bundle_below_subj)!=0) ) ? 1:0;
899
- }
900
- else
901
- {
902
- throw new IllegalStateException("Unknown op");
903
- }
904
-
905
- /* Update parity */
906
- parity_clip ^= edge.bundle_above[CLIP];
907
- parity_subj ^= edge.bundle_above[SUBJ];
908
-
909
- /* Update horizontal state */
910
- if (exists_clip!=0)
911
- {
912
- horiz_clip = HState.next_h_state[horiz_clip][((exists_clip - 1) << 1) + parity_clip];
834
+ float xb = edge.xb;
835
+
836
+ int vclass = VertexType.getType(tr, tl, br, bl);
837
+ switch (vclass) {
838
+ case VertexType.EMN:
839
+ tlist = new_tristrip(tlist, edge, xb, yb);
840
+ cf = edge;
841
+ break;
842
+ case VertexType.ERI:
843
+ edge.outp_above = cf.outp_above;
844
+ if (xb != cf.xb) {
845
+ VERTEX(edge, ABOVE, RIGHT, xb, yb);
846
+ }
847
+ cf = null;
848
+ break;
849
+ case VertexType.ELI:
850
+ VERTEX(edge, BELOW, LEFT, xb, yb);
851
+ edge.outp_above = null;
852
+ cf = edge;
853
+ break;
854
+ case VertexType.EMX:
855
+ if (xb != cf.xb) {
856
+ VERTEX(edge, BELOW, RIGHT, xb, yb);
857
+ }
858
+ edge.outp_above = null;
859
+ cf = null;
860
+ break;
861
+ case VertexType.IMN:
862
+ if (cft == VertexType.LED) {
863
+ if (cf.bot_y != yb) {
864
+ VERTEX(cf, BELOW, LEFT, cf.xb, yb);
913
865
  }
914
- if( exists_subj!=0)
915
- {
916
- horiz_subj = HState.next_h_state[horiz_subj][((exists_subj - 1) << 1) + parity_subj];
866
+ tlist = new_tristrip(tlist, cf, cf.xb, yb);
867
+ }
868
+ edge.outp_above = cf.outp_above;
869
+ VERTEX(edge, ABOVE, RIGHT, xb, yb);
870
+ break;
871
+ case VertexType.ILI:
872
+ tlist = new_tristrip(tlist, edge, xb, yb);
873
+ cf = edge;
874
+ cft = VertexType.ILI;
875
+ break;
876
+ case VertexType.IRI:
877
+ if (cft == VertexType.LED) {
878
+ if (cf.bot_y != yb) {
879
+ VERTEX(cf, BELOW, LEFT, cf.xb, yb);
917
880
  }
918
-
919
- if (contributing) // DIFFERENT!
920
- {
921
- float xb = edge.xb;
922
-
923
- int vclass = VertexType.getType( tr, tl, br, bl );
924
- switch (vclass)
925
- {
926
- case VertexType.EMN:
927
- tlist=new_tristrip(tlist, edge, xb, yb);
928
- cf= edge;
929
- break;
930
- case VertexType.ERI:
931
- edge.outp_above= cf.outp_above;
932
- if (xb != cf.xb)
933
- {
934
- VERTEX(edge, ABOVE, RIGHT, xb, yb);
935
- }
936
- cf= null;
937
- break;
938
- case VertexType.ELI:
939
- VERTEX(edge, BELOW, LEFT, xb, yb);
940
- edge.outp_above= null;
941
- cf= edge;
942
- break;
943
- case VertexType.EMX:
944
- if (xb != cf.xb)
945
- {
946
- VERTEX(edge, BELOW, RIGHT, xb, yb);
947
- }
948
- edge.outp_above = null;
949
- cf= null;
950
- break;
951
- case VertexType.IMN:
952
- if (cft == VertexType.LED)
953
- {
954
- if (cf.bot_y != yb)
955
- {
956
- VERTEX(cf, BELOW, LEFT, cf.xb, yb);
957
- }
958
- tlist=new_tristrip(tlist, cf, cf.xb, yb);
959
- }
960
- edge.outp_above= cf.outp_above;
961
- VERTEX(edge, ABOVE, RIGHT, xb, yb);
962
- break;
963
- case VertexType.ILI:
964
- tlist=new_tristrip(tlist, edge, xb, yb);
965
- cf= edge;
966
- cft= VertexType.ILI;
967
- break;
968
- case VertexType.IRI:
969
- if (cft == VertexType.LED)
970
- {
971
- if (cf.bot_y != yb)
972
- {
973
- VERTEX(cf, BELOW, LEFT, cf.xb, yb);
974
- }
975
- tlist=new_tristrip(tlist, cf, cf.xb, yb);
976
- }
977
- VERTEX(edge, BELOW, RIGHT, xb, yb);
978
- edge.outp_above= null;
979
- break;
980
- case VertexType.IMX:
981
- VERTEX(edge, BELOW, LEFT, xb, yb);
982
- edge.outp_above= null;
983
- cft= VertexType.IMX;
984
- break;
985
- case VertexType.IMM:
986
- VERTEX(edge, BELOW, LEFT, xb, yb);
987
- edge.outp_above= cf.outp_above;
988
- if (xb != cf.xb)
989
- {
990
- VERTEX(cf, ABOVE, RIGHT, xb, yb);
991
- }
992
- cf= edge;
993
- break;
994
- case VertexType.EMM:
995
- VERTEX(edge, BELOW, RIGHT, xb, yb);
996
- edge.outp_above= null;
997
- tlist=new_tristrip(tlist, edge, xb, yb);
998
- cf= edge;
999
- break;
1000
- case VertexType.LED:
1001
- if (edge.bot_y == yb)
1002
- VERTEX(edge, BELOW, LEFT, xb, yb);
1003
- edge.outp_above= edge.outp_below;
1004
- cf= edge;
1005
- cft= VertexType.LED;
1006
- break;
1007
- case VertexType.RED:
1008
- edge.outp_above= cf.outp_above;
1009
- if (cft == VertexType.LED)
1010
- {
1011
- if (cf.bot_y == yb)
1012
- {
1013
- VERTEX(edge, BELOW, RIGHT, xb, yb);
1014
- }
1015
- else
1016
- {
1017
- if (edge.bot_y == yb)
1018
- {
1019
- VERTEX(cf, BELOW, LEFT, cf.xb, yb);
1020
- VERTEX(edge, BELOW, RIGHT, xb, yb);
1021
- }
1022
- }
1023
- }
1024
- else
1025
- {
1026
- VERTEX(edge, BELOW, RIGHT, xb, yb);
1027
- VERTEX(edge, ABOVE, RIGHT, xb, yb);
1028
- }
1029
- cf= null;
1030
- break;
1031
- default:
1032
- break;
1033
- } /* End of switch */
1034
- } /* End of contributing conditional */
1035
- } /* End of edge exists conditional */
1036
- } /* End of AET loop */
1037
-
1038
- /* Delete terminating edges from the AET, otherwise compute xt */
1039
- for (EdgeNode edge = aet.top_node; (edge != null); edge = edge.next)
1040
- {
1041
- if (edge.top_y == yb)
1042
- {
1043
- EdgeNode prev_edge = edge.prev;
1044
- EdgeNode next_edge = edge.next;
1045
-
1046
- if (prev_edge != null)
1047
- prev_edge.next = next_edge;
1048
- else
1049
- aet.top_node = next_edge;
1050
-
1051
- if (next_edge != null )
1052
- next_edge.prev = prev_edge;
1053
-
1054
- /* Copy bundle head state to the adjacent tail edge if required */
1055
- if ((edge.bstate_below == BundleState.BUNDLE_HEAD) && (prev_edge!=null))
1056
- {
1057
- if (prev_edge.bstate_below == BundleState.BUNDLE_TAIL)
1058
- {
1059
- prev_edge.outp_below= edge.outp_below;
1060
- prev_edge.bstate_below= BundleState.UNBUNDLED;
1061
- if ( prev_edge.prev != null)
1062
- {
1063
- if (prev_edge.prev.bstate_below == BundleState.BUNDLE_TAIL)
1064
- {
1065
- prev_edge.bstate_below = BundleState.BUNDLE_HEAD;
1066
- }
1067
- }
1068
- }
881
+ tlist = new_tristrip(tlist, cf, cf.xb, yb);
882
+ }
883
+ VERTEX(edge, BELOW, RIGHT, xb, yb);
884
+ edge.outp_above = null;
885
+ break;
886
+ case VertexType.IMX:
887
+ VERTEX(edge, BELOW, LEFT, xb, yb);
888
+ edge.outp_above = null;
889
+ cft = VertexType.IMX;
890
+ break;
891
+ case VertexType.IMM:
892
+ VERTEX(edge, BELOW, LEFT, xb, yb);
893
+ edge.outp_above = cf.outp_above;
894
+ if (xb != cf.xb) {
895
+ VERTEX(cf, ABOVE, RIGHT, xb, yb);
896
+ }
897
+ cf = edge;
898
+ break;
899
+ case VertexType.EMM:
900
+ VERTEX(edge, BELOW, RIGHT, xb, yb);
901
+ edge.outp_above = null;
902
+ tlist = new_tristrip(tlist, edge, xb, yb);
903
+ cf = edge;
904
+ break;
905
+ case VertexType.LED:
906
+ if (edge.bot_y == yb) {
907
+ VERTEX(edge, BELOW, LEFT, xb, yb);
908
+ }
909
+ edge.outp_above = edge.outp_below;
910
+ cf = edge;
911
+ cft = VertexType.LED;
912
+ break;
913
+ case VertexType.RED:
914
+ edge.outp_above = cf.outp_above;
915
+ if (cft == VertexType.LED) {
916
+ if (cf.bot_y == yb) {
917
+ VERTEX(edge, BELOW, RIGHT, xb, yb);
918
+ } else {
919
+ if (edge.bot_y == yb) {
920
+ VERTEX(cf, BELOW, LEFT, cf.xb, yb);
921
+ VERTEX(edge, BELOW, RIGHT, xb, yb);
922
+ }
1069
923
  }
924
+ } else {
925
+ VERTEX(edge, BELOW, RIGHT, xb, yb);
926
+ VERTEX(edge, ABOVE, RIGHT, xb, yb);
927
+ }
928
+ cf = null;
929
+ break;
930
+ default:
931
+ break;
932
+ }
933
+ /* End of switch */
934
+ }
935
+ /* End of contributing conditional */
936
+ }
937
+ /* End of edge exists conditional */
938
+ }
939
+ /* End of AET loop */
940
+
941
+ /* Delete terminating edges from the AET, otherwise compute xt */
942
+ for (EdgeNode edge = aet.top_node; (edge != null); edge = edge.next) {
943
+ if (edge.top_y == yb) {
944
+ EdgeNode prev_edge = edge.prev;
945
+ EdgeNode next_edge = edge.next;
946
+
947
+ if (prev_edge != null) {
948
+ prev_edge.next = next_edge;
949
+ } else {
950
+ aet.top_node = next_edge;
951
+ }
952
+
953
+ if (next_edge != null) {
954
+ next_edge.prev = prev_edge;
955
+ }
956
+
957
+ /* Copy bundle head state to the adjacent tail edge if required */
958
+ if ((edge.bstate_below == BundleState.BUNDLE_HEAD) && (prev_edge != null)) {
959
+ if (prev_edge.bstate_below == BundleState.BUNDLE_TAIL) {
960
+ prev_edge.outp_below = edge.outp_below;
961
+ prev_edge.bstate_below = BundleState.UNBUNDLED;
962
+ if (prev_edge.prev != null) {
963
+ if (prev_edge.prev.bstate_below == BundleState.BUNDLE_TAIL) {
964
+ prev_edge.bstate_below = BundleState.BUNDLE_HEAD;
965
+ }
1070
966
  }
1071
- else
1072
- {
1073
- if (edge.top_y == yt)
1074
- edge.xt= edge.top_x;
1075
- else
1076
- edge.xt= edge.bot_x + edge.dx * (yt - edge.bot_y);
1077
- }
967
+ }
1078
968
  }
1079
-
1080
- if (scanbeam < sbte.sbt_entries )
1081
- {
1082
- /* === SCANBEAM INTERIOR PROCESSING ============================== */
1083
-
1084
- /* Build intersection table for the current scanbeam */
1085
- ItNodeTable it_table = new ItNodeTable();
1086
- it_table.build_intersection_table(aet, dy);
1087
-
1088
- /* Process each node in the intersection table */
1089
- for (ItNode intersect = it_table.top_node; (intersect != null); intersect = intersect.next)
1090
- {
1091
- e0= intersect.ie0;
1092
- e1= intersect.ie1;
1093
-
1094
- /* Only generate output for contributing intersections */
1095
- if ( ((e0.bundle_above[CLIP]!=0) || (e0.bundle_above[SUBJ]!=0)) &&
1096
- ((e1.bundle_above[CLIP]!=0) || (e1.bundle_above[SUBJ]!=0)))
1097
- {
1098
- PolygonNode p = e0.outp_above;
1099
- PolygonNode q = e1.outp_above;
1100
- float ix = intersect.point_x;
1101
- float iy = intersect.point_y + yb;
1102
-
1103
- int in_clip = ( ( (e0.bundle_above[CLIP]!=0) && !(e0.bside_clip!=0)) ||
1104
- ( (e1.bundle_above[CLIP]!=0) && (e1.bside_clip!=0)) ||
1105
- (!(e0.bundle_above[CLIP]!=0) && !(e1.bundle_above[CLIP]!=0) &&
1106
- (e0.bside_clip!=0) && (e1.bside_clip!=0) ) ) ? 1 : 0;
1107
-
1108
- int in_subj = ( ( (e0.bundle_above[SUBJ]!=0) && !(e0.bside_subj!=0)) ||
1109
- ( (e1.bundle_above[SUBJ]!=0) && (e1.bside_subj!=0)) ||
1110
- (!(e0.bundle_above[SUBJ]!=0) && !(e1.bundle_above[SUBJ]!=0) &&
1111
- (e0.bside_subj!=0) && (e1.bside_subj!=0) ) ) ? 1 : 0;
1112
-
1113
- int tr=0, tl=0, br=0, bl=0;
1114
- /* Determine quadrant occupancies */
1115
- if( (op == OperationType.GPC_DIFF) || (op == OperationType.GPC_INT) )
1116
- {
1117
- tr= ((in_clip!=0) && (in_subj!=0)) ? 1 : 0;
1118
- tl= (((in_clip ^ e1.bundle_above[CLIP])!=0) && ((in_subj ^ e1.bundle_above[SUBJ])!=0))?1:0;
1119
- br= (((in_clip ^ e0.bundle_above[CLIP])!=0) && ((in_subj ^ e0.bundle_above[SUBJ])!=0))?1:0;
1120
- bl= (((in_clip ^ e1.bundle_above[CLIP] ^ e0.bundle_above[CLIP])!=0) &&
1121
- ((in_subj ^ e1.bundle_above[SUBJ] ^ e0.bundle_above[SUBJ])!=0) ) ? 1:0;
1122
- }
1123
- else if( op == OperationType.GPC_XOR )
1124
- {
1125
- tr= (in_clip)^ (in_subj);
1126
- tl= (in_clip ^ e1.bundle_above[CLIP]) ^ (in_subj ^ e1.bundle_above[SUBJ]);
1127
- br= (in_clip ^ e0.bundle_above[CLIP]) ^ (in_subj ^ e0.bundle_above[SUBJ]);
1128
- bl= (in_clip ^ e1.bundle_above[CLIP] ^ e0.bundle_above[CLIP])
1129
- ^ (in_subj ^ e1.bundle_above[SUBJ] ^ e0.bundle_above[SUBJ]);
1130
- }
1131
- else if( op == OperationType.GPC_UNION )
1132
- {
1133
- tr= ((in_clip!=0) || (in_subj!=0)) ? 1 : 0;
1134
- tl= (((in_clip ^ e1.bundle_above[CLIP])!=0) || ((in_subj ^ e1.bundle_above[SUBJ])!=0)) ? 1 : 0;
1135
- br= (((in_clip ^ e0.bundle_above[CLIP])!=0) || ((in_subj ^ e0.bundle_above[SUBJ])!=0)) ? 1 : 0;
1136
- bl= (((in_clip ^ e1.bundle_above[CLIP] ^ e0.bundle_above[CLIP])!=0) ||
1137
- ((in_subj ^ e1.bundle_above[SUBJ] ^ e0.bundle_above[SUBJ])!=0)) ? 1 : 0;
1138
- }
1139
- else
1140
- {
1141
- throw new IllegalStateException("Unknown op type, "+op);
1142
- }
1143
-
1144
- EdgeNode next_edge = e1.next;
1145
- EdgeNode prev_edge = e0.prev;
1146
-
1147
- int vclass = VertexType.getType( tr, tl, br, bl );
1148
- switch (vclass)
1149
- {
1150
- case VertexType.EMN:
1151
- tlist=new_tristrip(tlist, e1, ix, iy);
1152
- e1.outp_above = e0.outp_above;
1153
- break;
1154
- case VertexType.ERI:
1155
- if (p != null)
1156
- {
1157
- px = P_EDGE(prev_edge, e0, ABOVE, px, iy);
1158
- VERTEX(prev_edge, ABOVE, LEFT, px, iy);
1159
- VERTEX(e0, ABOVE, RIGHT, ix, iy);
1160
- e1.outp_above= e0.outp_above;
1161
- e0.outp_above= null;
1162
- }
1163
- break;
1164
- case VertexType.ELI:
1165
- if (q != null)
1166
- {
1167
- nx = N_EDGE(next_edge, e1, ABOVE, nx, iy);
1168
- VERTEX(e1, ABOVE, LEFT, ix, iy);
1169
- VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
1170
- e0.outp_above= e1.outp_above;
1171
- e1.outp_above= null;
1172
- }
1173
- break;
1174
- case VertexType.EMX:
1175
- if ((p!=null) && (q!=null))
1176
- {
1177
- VERTEX(e0, ABOVE, LEFT, ix, iy);
1178
- e0.outp_above= null;
1179
- e1.outp_above= null;
1180
- }
1181
- break;
1182
- case VertexType.IMN:
1183
- px = P_EDGE(prev_edge, e0, ABOVE, px, iy);
1184
- VERTEX(prev_edge, ABOVE, LEFT, px, iy);
1185
- nx = N_EDGE(next_edge, e1, ABOVE, nx, iy);
1186
- VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
1187
- tlist=new_tristrip(tlist, prev_edge, px, iy);
1188
- e1.outp_above= prev_edge.outp_above;
1189
- VERTEX(e1, ABOVE, RIGHT, ix, iy);
1190
- tlist=new_tristrip(tlist, e0, ix, iy);
1191
- next_edge.outp_above= e0.outp_above;
1192
- VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
1193
- break;
1194
- case VertexType.ILI:
1195
- if (p != null)
1196
- {
1197
- VERTEX(e0, ABOVE, LEFT, ix, iy);
1198
- nx = N_EDGE(next_edge, e1, ABOVE, nx, iy);
1199
- VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
1200
- e1.outp_above= e0.outp_above;
1201
- e0.outp_above= null;
1202
- }
1203
- break;
1204
- case VertexType.IRI:
1205
- if (q!=null)
1206
- {
1207
- VERTEX(e1, ABOVE, RIGHT, ix, iy);
1208
- px = P_EDGE(prev_edge, e0, ABOVE, px, iy);
1209
- VERTEX(prev_edge, ABOVE, LEFT, px, iy);
1210
- e0.outp_above= e1.outp_above;
1211
- e1.outp_above= null;
1212
- }
1213
- break;
1214
- case VertexType.IMX:
1215
- if ((p!=null) && (q!=null))
1216
- {
1217
- VERTEX(e0, ABOVE, RIGHT, ix, iy);
1218
- VERTEX(e1, ABOVE, LEFT, ix, iy);
1219
- e0.outp_above= null;
1220
- e1.outp_above= null;
1221
- px = P_EDGE(prev_edge, e0, ABOVE, px, iy);
1222
- VERTEX(prev_edge, ABOVE, LEFT, px, iy);
1223
- tlist=new_tristrip(tlist, prev_edge, px, iy);
1224
- nx = N_EDGE(next_edge, e1, ABOVE, nx, iy);
1225
- VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
1226
- next_edge.outp_above= prev_edge.outp_above;
1227
- VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
1228
- }
1229
- break;
1230
- case VertexType.IMM:
1231
- if ((p!=null) && (q!=null))
1232
- {
1233
- VERTEX(e0, ABOVE, RIGHT, ix, iy);
1234
- VERTEX(e1, ABOVE, LEFT, ix, iy);
1235
- px = P_EDGE(prev_edge, e0, ABOVE, px, iy);
1236
- VERTEX(prev_edge, ABOVE, LEFT, px, iy);
1237
- tlist=new_tristrip(tlist, prev_edge, px, iy);
1238
- nx = N_EDGE(next_edge, e1, ABOVE, nx, iy);
1239
- VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
1240
- e1.outp_above= prev_edge.outp_above;
1241
- VERTEX(e1, ABOVE, RIGHT, ix, iy);
1242
- tlist=new_tristrip(tlist, e0, ix, iy);
1243
- next_edge.outp_above= e0.outp_above;
1244
- VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
1245
- }
1246
- break;
1247
- case VertexType.EMM:
1248
- if ((p!=null) && (q!=null))
1249
- {
1250
- VERTEX(e0, ABOVE, LEFT, ix, iy);
1251
- tlist=new_tristrip(tlist, e1, ix, iy);
1252
- e1.outp_above = e0.outp_above;
1253
- }
1254
- break;
1255
- default:
1256
- break;
1257
- } /* End of switch */
1258
- } /* End of contributing intersection conditional */
1259
-
1260
- /* Swap bundle sides in response to edge crossing */
1261
- if (e0.bundle_above[CLIP]!=0)
1262
- e1.bside_clip = (e1.bside_clip==0)?1:0;
1263
- if (e1.bundle_above[CLIP]!=0)
1264
- e0.bside_clip= (e0.bside_clip==0)?1:0;
1265
- if (e0.bundle_above[SUBJ]!=0)
1266
- e1.bside_subj= (e1.bside_subj==0)?1:0;
1267
- if (e1.bundle_above[SUBJ]!=0)
1268
- e0.bside_subj= (e0.bside_subj==0)?1:0;
1269
-
1270
- /* Swap e0 and e1 bundles in the AET */
1271
- EdgeNode prev_edge = e0.prev;
1272
- EdgeNode next_edge = e1.next;
1273
- if (next_edge != null)
1274
- {
1275
- next_edge.prev = e0;
1276
- }
1277
-
1278
- if (e0.bstate_above == BundleState.BUNDLE_HEAD)
1279
- {
1280
- boolean search = true;
1281
- while (search)
1282
- {
1283
- prev_edge= prev_edge.prev;
1284
- if (prev_edge != null)
1285
- {
1286
- if (prev_edge.bundle_above[CLIP]!=0
1287
- || prev_edge.bundle_above[SUBJ]!=0
1288
- || (prev_edge.bstate_above == BundleState.BUNDLE_HEAD))
1289
- {
1290
- search= false;
1291
- }
1292
- }
1293
- else
1294
- {
1295
- search= false;
1296
- }
1297
- }
1298
- }
1299
- if (prev_edge == null)
1300
- {
1301
- e1.next = aet.top_node;
1302
- aet.top_node = e0.next;
1303
- }
1304
- else
1305
- {
1306
- e1.next = prev_edge.next;
1307
- prev_edge.next = e0.next;
1308
- }
1309
- e0.next.prev = prev_edge;
1310
- e1.next.prev = e1;
1311
- e0.next = next_edge;
1312
- } /* End of IT loop*/
1313
-
1314
- /* Prepare for next scanbeam */
1315
- for ( EdgeNode edge = aet.top_node; (edge != null); edge = edge.next)
1316
- {
1317
- EdgeNode next_edge = edge.next;
1318
- EdgeNode succ_edge = edge.succ;
1319
- if ((edge.top_y == yt) && (succ_edge!=null))
1320
- {
1321
- /* Replace AET edge by its successor */
1322
- succ_edge.outp_below= edge.outp_above;
1323
- succ_edge.bstate_below= edge.bstate_above;
1324
- succ_edge.bundle_below_clip= edge.bundle_above[CLIP];
1325
- succ_edge.bundle_below_subj= edge.bundle_above[SUBJ];
1326
- EdgeNode prev_edge = edge.prev;
1327
- if ( prev_edge != null )
1328
- prev_edge.next = succ_edge;
1329
- else
1330
- aet.top_node = succ_edge;
1331
- if (next_edge != null)
1332
- next_edge.prev= succ_edge;
1333
- succ_edge.prev = prev_edge;
1334
- succ_edge.next = next_edge;
1335
- }
1336
- else
1337
- {
1338
- /* Update this edge */
1339
- edge.outp_below= edge.outp_above;
1340
- edge.bstate_below= edge.bstate_above;
1341
- edge.bundle_below_clip= edge.bundle_above[CLIP];
1342
- edge.bundle_below_subj= edge.bundle_above[SUBJ];
1343
- edge.xb= edge.xt;
1344
- }
1345
- edge.outp_above= null;
969
+ } else {
970
+ if (edge.top_y == yt) {
971
+ edge.xt = edge.top_x;
972
+ } else {
973
+ edge.xt = edge.bot_x + edge.dx * (yt - edge.bot_y);
974
+ }
975
+ }
976
+ }
977
+
978
+ if (scanbeam < sbte.sbt_entries) {
979
+ /* === SCANBEAM INTERIOR PROCESSING ============================== */
980
+
981
+ /* Build intersection table for the current scanbeam */
982
+ ItNodeTable it_table = new ItNodeTable();
983
+ it_table.build_intersection_table(aet, dy);
984
+
985
+ /* Process each node in the intersection table */
986
+ for (ItNode intersect = it_table.top_node; (intersect != null); intersect = intersect.next) {
987
+ e0 = intersect.ie0;
988
+ e1 = intersect.ie1;
989
+
990
+ /* Only generate output for contributing intersections */
991
+ if (((e0.bundle_above[CLIP] != 0) || (e0.bundle_above[SUBJ] != 0))
992
+ && ((e1.bundle_above[CLIP] != 0) || (e1.bundle_above[SUBJ] != 0))) {
993
+ PolygonNode p = e0.outp_above;
994
+ PolygonNode q = e1.outp_above;
995
+ float ix = intersect.point_x;
996
+ float iy = intersect.point_y + yb;
997
+
998
+ int in_clip = (((e0.bundle_above[CLIP] != 0) && !(e0.bside_clip != 0))
999
+ || ((e1.bundle_above[CLIP] != 0) && (e1.bside_clip != 0))
1000
+ || (!(e0.bundle_above[CLIP] != 0) && !(e1.bundle_above[CLIP] != 0)
1001
+ && (e0.bside_clip != 0) && (e1.bside_clip != 0))) ? 1 : 0;
1002
+
1003
+ int in_subj = (((e0.bundle_above[SUBJ] != 0) && !(e0.bside_subj != 0))
1004
+ || ((e1.bundle_above[SUBJ] != 0) && (e1.bside_subj != 0))
1005
+ || (!(e0.bundle_above[SUBJ] != 0) && !(e1.bundle_above[SUBJ] != 0)
1006
+ && (e0.bside_subj != 0) && (e1.bside_subj != 0))) ? 1 : 0;
1007
+
1008
+ int tr = 0, tl = 0, br = 0, bl = 0;
1009
+ /* Determine quadrant occupancies */
1010
+ if ((op == OperationType.GPC_DIFF) || (op == OperationType.GPC_INT)) {
1011
+ tr = ((in_clip != 0) && (in_subj != 0)) ? 1 : 0;
1012
+ tl = (((in_clip ^ e1.bundle_above[CLIP]) != 0) && ((in_subj ^ e1.bundle_above[SUBJ]) != 0)) ? 1 : 0;
1013
+ br = (((in_clip ^ e0.bundle_above[CLIP]) != 0) && ((in_subj ^ e0.bundle_above[SUBJ]) != 0)) ? 1 : 0;
1014
+ bl = (((in_clip ^ e1.bundle_above[CLIP] ^ e0.bundle_above[CLIP]) != 0)
1015
+ && ((in_subj ^ e1.bundle_above[SUBJ] ^ e0.bundle_above[SUBJ]) != 0)) ? 1 : 0;
1016
+ } else if (op == OperationType.GPC_XOR) {
1017
+ tr = (in_clip) ^ (in_subj);
1018
+ tl = (in_clip ^ e1.bundle_above[CLIP]) ^ (in_subj ^ e1.bundle_above[SUBJ]);
1019
+ br = (in_clip ^ e0.bundle_above[CLIP]) ^ (in_subj ^ e0.bundle_above[SUBJ]);
1020
+ bl = (in_clip ^ e1.bundle_above[CLIP] ^ e0.bundle_above[CLIP])
1021
+ ^ (in_subj ^ e1.bundle_above[SUBJ] ^ e0.bundle_above[SUBJ]);
1022
+ } else if (op == OperationType.GPC_UNION) {
1023
+ tr = ((in_clip != 0) || (in_subj != 0)) ? 1 : 0;
1024
+ tl = (((in_clip ^ e1.bundle_above[CLIP]) != 0) || ((in_subj ^ e1.bundle_above[SUBJ]) != 0)) ? 1 : 0;
1025
+ br = (((in_clip ^ e0.bundle_above[CLIP]) != 0) || ((in_subj ^ e0.bundle_above[SUBJ]) != 0)) ? 1 : 0;
1026
+ bl = (((in_clip ^ e1.bundle_above[CLIP] ^ e0.bundle_above[CLIP]) != 0)
1027
+ || ((in_subj ^ e1.bundle_above[SUBJ] ^ e0.bundle_above[SUBJ]) != 0)) ? 1 : 0;
1028
+ } else {
1029
+ throw new IllegalStateException("Unknown op type, " + op);
1030
+ }
1031
+
1032
+ EdgeNode next_edge = e1.next;
1033
+ EdgeNode prev_edge = e0.prev;
1034
+
1035
+ int vclass = VertexType.getType(tr, tl, br, bl);
1036
+ switch (vclass) {
1037
+ case VertexType.EMN:
1038
+ tlist = new_tristrip(tlist, e1, ix, iy);
1039
+ e1.outp_above = e0.outp_above;
1040
+ break;
1041
+ case VertexType.ERI:
1042
+ if (p != null) {
1043
+ px = P_EDGE(prev_edge, e0, ABOVE, px, iy);
1044
+ VERTEX(prev_edge, ABOVE, LEFT, px, iy);
1045
+ VERTEX(e0, ABOVE, RIGHT, ix, iy);
1046
+ e1.outp_above = e0.outp_above;
1047
+ e0.outp_above = null;
1048
+ }
1049
+ break;
1050
+ case VertexType.ELI:
1051
+ if (q != null) {
1052
+ nx = N_EDGE(next_edge, e1, ABOVE, nx, iy);
1053
+ VERTEX(e1, ABOVE, LEFT, ix, iy);
1054
+ VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
1055
+ e0.outp_above = e1.outp_above;
1056
+ e1.outp_above = null;
1057
+ }
1058
+ break;
1059
+ case VertexType.EMX:
1060
+ if ((p != null) && (q != null)) {
1061
+ VERTEX(e0, ABOVE, LEFT, ix, iy);
1062
+ e0.outp_above = null;
1063
+ e1.outp_above = null;
1064
+ }
1065
+ break;
1066
+ case VertexType.IMN:
1067
+ px = P_EDGE(prev_edge, e0, ABOVE, px, iy);
1068
+ VERTEX(prev_edge, ABOVE, LEFT, px, iy);
1069
+ nx = N_EDGE(next_edge, e1, ABOVE, nx, iy);
1070
+ VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
1071
+ tlist = new_tristrip(tlist, prev_edge, px, iy);
1072
+ e1.outp_above = prev_edge.outp_above;
1073
+ VERTEX(e1, ABOVE, RIGHT, ix, iy);
1074
+ tlist = new_tristrip(tlist, e0, ix, iy);
1075
+ next_edge.outp_above = e0.outp_above;
1076
+ VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
1077
+ break;
1078
+ case VertexType.ILI:
1079
+ if (p != null) {
1080
+ VERTEX(e0, ABOVE, LEFT, ix, iy);
1081
+ nx = N_EDGE(next_edge, e1, ABOVE, nx, iy);
1082
+ VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
1083
+ e1.outp_above = e0.outp_above;
1084
+ e0.outp_above = null;
1085
+ }
1086
+ break;
1087
+ case VertexType.IRI:
1088
+ if (q != null) {
1089
+ VERTEX(e1, ABOVE, RIGHT, ix, iy);
1090
+ px = P_EDGE(prev_edge, e0, ABOVE, px, iy);
1091
+ VERTEX(prev_edge, ABOVE, LEFT, px, iy);
1092
+ e0.outp_above = e1.outp_above;
1093
+ e1.outp_above = null;
1094
+ }
1095
+ break;
1096
+ case VertexType.IMX:
1097
+ if ((p != null) && (q != null)) {
1098
+ VERTEX(e0, ABOVE, RIGHT, ix, iy);
1099
+ VERTEX(e1, ABOVE, LEFT, ix, iy);
1100
+ e0.outp_above = null;
1101
+ e1.outp_above = null;
1102
+ px = P_EDGE(prev_edge, e0, ABOVE, px, iy);
1103
+ VERTEX(prev_edge, ABOVE, LEFT, px, iy);
1104
+ tlist = new_tristrip(tlist, prev_edge, px, iy);
1105
+ nx = N_EDGE(next_edge, e1, ABOVE, nx, iy);
1106
+ VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
1107
+ next_edge.outp_above = prev_edge.outp_above;
1108
+ VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
1109
+ }
1110
+ break;
1111
+ case VertexType.IMM:
1112
+ if ((p != null) && (q != null)) {
1113
+ VERTEX(e0, ABOVE, RIGHT, ix, iy);
1114
+ VERTEX(e1, ABOVE, LEFT, ix, iy);
1115
+ px = P_EDGE(prev_edge, e0, ABOVE, px, iy);
1116
+ VERTEX(prev_edge, ABOVE, LEFT, px, iy);
1117
+ tlist = new_tristrip(tlist, prev_edge, px, iy);
1118
+ nx = N_EDGE(next_edge, e1, ABOVE, nx, iy);
1119
+ VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
1120
+ e1.outp_above = prev_edge.outp_above;
1121
+ VERTEX(e1, ABOVE, RIGHT, ix, iy);
1122
+ tlist = new_tristrip(tlist, e0, ix, iy);
1123
+ next_edge.outp_above = e0.outp_above;
1124
+ VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
1125
+ }
1126
+ break;
1127
+ case VertexType.EMM:
1128
+ if ((p != null) && (q != null)) {
1129
+ VERTEX(e0, ABOVE, LEFT, ix, iy);
1130
+ tlist = new_tristrip(tlist, e1, ix, iy);
1131
+ e1.outp_above = e0.outp_above;
1132
+ }
1133
+ break;
1134
+ default:
1135
+ break;
1136
+ }
1137
+ /* End of switch */
1138
+ }
1139
+ /* End of contributing intersection conditional */
1140
+
1141
+ /* Swap bundle sides in response to edge crossing */
1142
+ if (e0.bundle_above[CLIP] != 0) {
1143
+ e1.bside_clip = (e1.bside_clip == 0) ? 1 : 0;
1144
+ }
1145
+ if (e1.bundle_above[CLIP] != 0) {
1146
+ e0.bside_clip = (e0.bside_clip == 0) ? 1 : 0;
1147
+ }
1148
+ if (e0.bundle_above[SUBJ] != 0) {
1149
+ e1.bside_subj = (e1.bside_subj == 0) ? 1 : 0;
1150
+ }
1151
+ if (e1.bundle_above[SUBJ] != 0) {
1152
+ e0.bside_subj = (e0.bside_subj == 0) ? 1 : 0;
1153
+ }
1154
+
1155
+ /* Swap e0 and e1 bundles in the AET */
1156
+ EdgeNode prev_edge = e0.prev;
1157
+ EdgeNode next_edge = e1.next;
1158
+ if (next_edge != null) {
1159
+ next_edge.prev = e0;
1160
+ }
1161
+
1162
+ if (e0.bstate_above == BundleState.BUNDLE_HEAD) {
1163
+ boolean search = true;
1164
+ while (search) {
1165
+ prev_edge = prev_edge.prev;
1166
+ if (prev_edge != null) {
1167
+ if (prev_edge.bundle_above[CLIP] != 0
1168
+ || prev_edge.bundle_above[SUBJ] != 0
1169
+ || (prev_edge.bstate_above == BundleState.BUNDLE_HEAD)) {
1170
+ search = false;
1171
+ }
1172
+ } else {
1173
+ search = false;
1346
1174
  }
1175
+ }
1347
1176
  }
1348
- } /* === END OF SCANBEAM PROCESSING ================================== */
1349
-
1350
- /* Generate result tristrip from tlist */
1177
+ if (prev_edge == null) {
1178
+ e1.next = aet.top_node;
1179
+ aet.top_node = e0.next;
1180
+ } else {
1181
+ e1.next = prev_edge.next;
1182
+ prev_edge.next = e0.next;
1183
+ }
1184
+ e0.next.prev = prev_edge;
1185
+ e1.next.prev = e1;
1186
+ e0.next = next_edge;
1187
+ }
1188
+ /* End of IT loop*/
1189
+
1190
+ /* Prepare for next scanbeam */
1191
+ for (EdgeNode edge = aet.top_node; (edge != null); edge = edge.next) {
1192
+ EdgeNode next_edge = edge.next;
1193
+ EdgeNode succ_edge = edge.succ;
1194
+ if ((edge.top_y == yt) && (succ_edge != null)) {
1195
+ /* Replace AET edge by its successor */
1196
+ succ_edge.outp_below = edge.outp_above;
1197
+ succ_edge.bstate_below = edge.bstate_above;
1198
+ succ_edge.bundle_below_clip = edge.bundle_above[CLIP];
1199
+ succ_edge.bundle_below_subj = edge.bundle_above[SUBJ];
1200
+ EdgeNode prev_edge = edge.prev;
1201
+ if (prev_edge != null) {
1202
+ prev_edge.next = succ_edge;
1203
+ } else {
1204
+ aet.top_node = succ_edge;
1205
+ }
1206
+ if (next_edge != null) {
1207
+ next_edge.prev = succ_edge;
1208
+ }
1209
+ succ_edge.prev = prev_edge;
1210
+ succ_edge.next = next_edge;
1211
+ } else {
1212
+ /* Update this edge */
1213
+ edge.outp_below = edge.outp_above;
1214
+ edge.bstate_below = edge.bstate_above;
1215
+ edge.bundle_below_clip = edge.bundle_above[CLIP];
1216
+ edge.bundle_below_subj = edge.bundle_above[SUBJ];
1217
+ edge.xb = edge.xt;
1218
+ }
1219
+ edge.outp_above = null;
1220
+ }
1221
+ }
1222
+ }
1223
+ /* === END OF SCANBEAM PROCESSING ================================== */
1224
+
1225
+ /* Generate result tristrip from tlist */
1351
1226
  VertexNode lt, ltn, rt, rtn;
1352
1227
  PolygonNode tnn, tn;
1353
1228
  RMesh result = new RMesh();
1354
- if (count_tristrips(tlist) > 0)
1355
- {
1356
- int s, v;
1357
-
1358
- s= 0;
1359
- for (tn= tlist; tn!=null; tn= tnn)
1360
- {
1361
- tnn= tn.next;
1362
-
1363
- if (tn.active > 2)
1364
- {
1365
- /* Valid tristrip: copy the vertices and free the heap */
1366
- RStrip strip = new RStrip();
1367
- v= 0;
1368
- if (INVERT_TRISTRIPS == true)
1369
- {
1370
- lt= tn.v_right;
1371
- rt= tn.v_left;
1372
- }
1373
- else
1374
- {
1375
- lt= tn.v_left;
1376
- rt= tn.v_right;
1377
- }
1378
- while (lt!=null || rt!=null)
1379
- {
1380
- if (lt!=null)
1381
- {
1382
- ltn= lt.next;
1383
- strip.add(lt.x,lt.y);
1384
- v++;
1385
- lt= ltn;
1386
- }
1387
- if (rt!=null)
1388
- {
1389
- rtn= rt.next;
1390
- strip.add(rt.x,rt.y);
1391
- v++;
1392
- rt= rtn;
1393
- }
1394
- }
1395
- result.addStrip(strip);
1396
- s++;
1397
- }
1398
- else
1399
- {
1400
- /* Invalid tristrip: just free the heap */
1401
- for (lt= tn.v_left; lt!=null; lt= ltn)
1402
- {
1403
- ltn= lt.next;
1404
- }
1405
- for (rt= tn.v_right; rt!=null; rt= rtn)
1406
- {
1407
- rtn= rt.next;
1408
- }
1409
- }
1229
+ if (count_tristrips(tlist) > 0) {
1230
+ int s, v;
1231
+
1232
+ s = 0;
1233
+ for (tn = tlist; tn != null; tn = tnn) {
1234
+ tnn = tn.next;
1235
+
1236
+ if (tn.active > 2) {
1237
+ /* Valid tristrip: copy the vertices and free the heap */
1238
+ RStrip strip = new RStrip();
1239
+ v = 0;
1240
+ if (INVERT_TRISTRIPS == true) {
1241
+ lt = tn.v_right;
1242
+ rt = tn.v_left;
1243
+ } else {
1244
+ lt = tn.v_left;
1245
+ rt = tn.v_right;
1410
1246
  }
1247
+ while (lt != null || rt != null) {
1248
+ if (lt != null) {
1249
+ ltn = lt.next;
1250
+ strip.add(lt.x, lt.y);
1251
+ v++;
1252
+ lt = ltn;
1253
+ }
1254
+ if (rt != null) {
1255
+ rtn = rt.next;
1256
+ strip.add(rt.x, rt.y);
1257
+ v++;
1258
+ rt = rtn;
1259
+ }
1260
+ }
1261
+ result.addStrip(strip);
1262
+ s++;
1263
+ } else {
1264
+ /* Invalid tristrip: just free the heap */
1265
+ for (lt = tn.v_left; lt != null; lt = ltn) {
1266
+ ltn = lt.next;
1267
+ }
1268
+ for (rt = tn.v_right; rt != null; rt = rtn) {
1269
+ rtn = rt.next;
1270
+ }
1271
+ }
1411
1272
  }
1273
+ }
1412
1274
  return result;
1413
1275
  }
1414
-
1415
- public static RMesh polygonToMesh(RPolygon s)
1416
- {
1276
+
1277
+ public static RMesh polygonToMesh(RPolygon s) {
1417
1278
  RPolygon c = new RPolygon();
1418
1279
  RPolygon s_clean = s.removeOpenContours();
1419
1280
  /*
@@ -1426,1230 +1287,1086 @@ class FastRClip
1426
1287
  System.out.println(" Point " + (j + 1) + "/" + s_clean.contours[i].countPoints() + ":" + "(" + s_clean.contours[i].points[j].x + ", " + s_clean.contours[i].points[j].y + ")");
1427
1288
  }
1428
1289
  }
1429
- */
1290
+ */
1430
1291
  return clip(OperationType.GPC_UNION, s_clean, c);
1431
1292
  }
1432
-
1433
- private static boolean EQ(float a, float b)
1434
- {
1293
+
1294
+ private static boolean EQ(float a, float b) {
1435
1295
  return (Math.abs(a - b) <= GPC_EPSILON);
1436
1296
  }
1437
-
1438
- private static int PREV_INDEX( int i, int n)
1439
- {
1297
+
1298
+ private static int PREV_INDEX(int i, int n) {
1440
1299
  return ((i - 1 + n) % n);
1441
1300
  }
1442
-
1443
- private static int NEXT_INDEX(int i, int n)
1444
- {
1445
- return ((i + 1 ) % n);
1301
+
1302
+ private static int NEXT_INDEX(int i, int n) {
1303
+ return ((i + 1) % n);
1446
1304
  }
1447
-
1448
- private static boolean OPTIMAL( RPolygon p, int i )
1449
- {
1450
- return (p.getY(PREV_INDEX(i, p.getNumPoints())) != p.getY(i)) ||
1451
- (p.getY(NEXT_INDEX(i, p.getNumPoints())) != p.getY(i));
1305
+
1306
+ private static boolean OPTIMAL(RPolygon p, int i) {
1307
+ return (p.getY(PREV_INDEX(i, p.getNumPoints())) != p.getY(i))
1308
+ || (p.getY(NEXT_INDEX(i, p.getNumPoints())) != p.getY(i));
1452
1309
  }
1453
-
1310
+
1454
1311
  // TODO: demacro-ize this
1455
- private static void VERTEX( EdgeNode e, int p, int s, float x, float y )
1456
- {
1457
- if(p == ABOVE) {
1458
- if(s == RIGHT) {
1459
- e.outp_above.v_right = add_vertex(e.outp_above.v_right, x, y);
1460
- } else if(s == LEFT) {
1461
- e.outp_above.v_left = add_vertex(e.outp_above.v_left, x, y);
1462
- } else {
1463
- throw new IllegalStateException("bogus s value");
1464
- }
1465
-
1466
- e.outp_above.active++;
1467
-
1468
- } else if (p == BELOW) {
1469
- if(s == RIGHT) {
1470
- e.outp_below.v_right = add_vertex(e.outp_below.v_right, x, y);
1471
- } else if(s == LEFT) {
1472
- e.outp_below.v_left = add_vertex(e.outp_below.v_left, x, y);
1473
- } else {
1474
- throw new IllegalStateException("bogus s value");
1475
- }
1476
-
1477
- e.outp_below.active++;
1478
-
1479
- } else {
1480
- throw new IllegalStateException("bogus p value");
1312
+ private static void VERTEX(EdgeNode e, int p, int s, float x, float y) {
1313
+ switch (p) {
1314
+ case ABOVE:
1315
+ switch (s) {
1316
+ case RIGHT:
1317
+ e.outp_above.v_right = add_vertex(e.outp_above.v_right, x, y);
1318
+ break;
1319
+ case LEFT:
1320
+ e.outp_above.v_left = add_vertex(e.outp_above.v_left, x, y);
1321
+ break;
1322
+ default:
1323
+ throw new IllegalStateException("bogus s value");
1324
+ }
1325
+ e.outp_above.active++;
1326
+ break;
1327
+ case BELOW:
1328
+ switch (s) {
1329
+ case RIGHT:
1330
+ e.outp_below.v_right = add_vertex(e.outp_below.v_right, x, y);
1331
+ break;
1332
+ case LEFT:
1333
+ e.outp_below.v_left = add_vertex(e.outp_below.v_left, x, y);
1334
+ break;
1335
+ default:
1336
+ throw new IllegalStateException("bogus s value");
1337
+ }
1338
+ e.outp_below.active++;
1339
+ break;
1340
+ default:
1341
+ throw new IllegalStateException("bogus p value");
1481
1342
  }
1482
1343
  }
1483
-
1484
- private static float P_EDGE( EdgeNode d, EdgeNode e, int p, float i, float j)
1485
- {
1486
- if(p == ABOVE) {
1487
-
1488
- d = e;
1489
- do {
1490
- d = d.prev;
1491
- } while(d.outp_above == null);
1492
- return d.bot_x + d.dx*(j-d.bot_y);
1493
-
1494
- } else if (p == BELOW) {
1495
-
1496
- d = e;
1497
- do {
1498
- d = d.prev;
1499
- } while(d.outp_below == null);
1500
- return d.bot_x + d.dx*(j-d.bot_y);
1501
-
1502
- } else {
1503
- throw new IllegalStateException("bogus p value");
1344
+
1345
+ private static float P_EDGE(EdgeNode d, EdgeNode e, int p, float i, float j) {
1346
+ switch (p) {
1347
+ case ABOVE:
1348
+ d = e;
1349
+ do {
1350
+ d = d.prev;
1351
+ } while (d.outp_above == null);
1352
+ return d.bot_x + d.dx * (j - d.bot_y);
1353
+ case BELOW:
1354
+ d = e;
1355
+ do {
1356
+ d = d.prev;
1357
+ } while (d.outp_below == null);
1358
+ return d.bot_x + d.dx * (j - d.bot_y);
1359
+ default:
1360
+ throw new IllegalStateException("bogus p value");
1504
1361
  }
1505
1362
  }
1506
-
1507
- private static float N_EDGE( EdgeNode d, EdgeNode e, int p, float i, float j)
1508
- {
1509
- if(p == ABOVE) {
1510
-
1511
- d = e;
1512
- do {
1513
- d= d.next;
1514
- } while(d.outp_above == null);
1515
- return d.bot_x + d.dx*(j-d.bot_y);
1516
-
1517
- } else if(p == BELOW) {
1518
-
1519
- d = e;
1520
- do {
1521
- d= d.next;
1522
- } while(d.outp_below == null);
1523
- return d.bot_x + d.dx*(j-d.bot_y);
1524
-
1525
- } else {
1526
- throw new IllegalStateException("bogus p value");
1363
+
1364
+ private static float N_EDGE(EdgeNode d, EdgeNode e, int p, float i, float j) {
1365
+ switch (p) {
1366
+ case ABOVE:
1367
+ d = e;
1368
+ do {
1369
+ d = d.next;
1370
+ } while (d.outp_above == null);
1371
+ return d.bot_x + d.dx * (j - d.bot_y);
1372
+ case BELOW:
1373
+ d = e;
1374
+ do {
1375
+ d = d.next;
1376
+ } while (d.outp_below == null);
1377
+ return d.bot_x + d.dx * (j - d.bot_y);
1378
+ default:
1379
+ throw new IllegalStateException("bogus p value");
1527
1380
  }
1528
1381
  }
1529
-
1530
- private static RRectangle[] create_contour_bboxes( RPolygon p )
1531
- {
1382
+
1383
+ private static RRectangle[] create_contour_bboxes(RPolygon p) {
1532
1384
  RRectangle[] box = new RRectangle[p.getNumInnerPoly()];
1533
-
1385
+
1534
1386
  /* Construct contour bounding boxes */
1535
- for ( int c= 0; c < p.getNumInnerPoly(); c++)
1536
- {
1537
- RPolygon inner_poly = p.getInnerPoly(c);
1538
- box[c] = inner_poly.getBBox();
1539
- }
1540
- return box;
1387
+ for (int c = 0; c < p.getNumInnerPoly(); c++) {
1388
+ RPolygon inner_poly = p.getInnerPoly(c);
1389
+ box[c] = inner_poly.getBBox();
1390
+ }
1391
+ return box;
1541
1392
  }
1542
-
1543
- private static void minimax_test( RPolygon subj, RPolygon clip, OperationType op )
1544
- {
1393
+
1394
+ private static void minimax_test(RPolygon subj, RPolygon clip, OperationType op) {
1545
1395
  RRectangle[] s_bbox = create_contour_bboxes(subj);
1546
1396
  RRectangle[] c_bbox = create_contour_bboxes(clip);
1547
-
1397
+
1548
1398
  int subj_num_poly = subj.getNumInnerPoly();
1549
1399
  int clip_num_poly = clip.getNumInnerPoly();
1550
1400
  boolean[][] o_table = new boolean[subj_num_poly][clip_num_poly];
1551
-
1401
+
1552
1402
  /* Check all subject contour bounding boxes against clip boxes */
1553
- for( int s = 0; s < subj_num_poly; s++ )
1554
- {
1555
- for( int c= 0; c < clip_num_poly; c++ )
1556
- {
1557
- o_table[s][c] =
1558
- (!((s_bbox[s].getMaxX() < c_bbox[c].getMinX()) ||
1559
- (s_bbox[s].getMinX() > c_bbox[c].getMaxX()))) &&
1560
- (!((s_bbox[s].getMaxY() < c_bbox[c].getMinY()) ||
1561
- (s_bbox[s].getMinY() > c_bbox[c].getMaxY())));
1562
- }
1403
+ for (int s = 0; s < subj_num_poly; s++) {
1404
+ for (int c = 0; c < clip_num_poly; c++) {
1405
+ o_table[s][c]
1406
+ = (!((s_bbox[s].getMaxX() < c_bbox[c].getMinX())
1407
+ || (s_bbox[s].getMinX() > c_bbox[c].getMaxX())))
1408
+ && (!((s_bbox[s].getMaxY() < c_bbox[c].getMinY())
1409
+ || (s_bbox[s].getMinY() > c_bbox[c].getMaxY())));
1563
1410
  }
1564
-
1411
+ }
1412
+
1565
1413
  /* For each clip contour, search for any subject contour overlaps */
1566
- for( int c = 0; c < clip_num_poly; c++ )
1567
- {
1568
- boolean overlap = false;
1569
- for( int s = 0; !overlap && (s < subj_num_poly); s++)
1570
- {
1571
- overlap = o_table[s][c];
1572
- }
1573
- if (!overlap)
1574
- {
1575
- clip.setContributing( c, false ); // Flag non contributing status
1576
- }
1577
- }
1578
-
1579
- if (op == OperationType.GPC_INT)
1580
- {
1581
- /* For each subject contour, search for any clip contour overlaps */
1582
- for ( int s= 0; s < subj_num_poly; s++)
1583
- {
1584
- boolean overlap = false;
1585
- for ( int c= 0; !overlap && (c < clip_num_poly); c++)
1586
- {
1587
- overlap = o_table[s][c];
1588
- }
1589
- if (!overlap)
1590
- {
1591
- subj.setContributing( s, false ); // Flag non contributing status
1592
- }
1593
- }
1414
+ for (int c = 0; c < clip_num_poly; c++) {
1415
+ boolean overlap = false;
1416
+ for (int s = 0; !overlap && (s < subj_num_poly); s++) {
1417
+ overlap = o_table[s][c];
1594
1418
  }
1595
- }
1596
-
1597
- private static LmtNode bound_list( LmtTable lmt_table, float y )
1598
- {
1599
- if( lmt_table.top_node == null )
1600
- {
1601
- lmt_table.top_node = new LmtNode(y);
1602
- return lmt_table.top_node;
1419
+ if (!overlap) {
1420
+ clip.setContributing(c, false); // Flag non contributing status
1603
1421
  }
1604
- else
1605
- {
1606
- LmtNode prev = null;
1607
- LmtNode node = lmt_table.top_node;
1608
- boolean done = false;
1609
- while( !done )
1610
- {
1611
- if( y < node.y )
1612
- {
1613
- /* Insert a new LMT node before the current node */
1614
- LmtNode existing_node = node;
1615
- node = new LmtNode(y);
1616
- node.next = existing_node;
1617
- if( prev == null )
1618
- {
1619
- lmt_table.top_node = node;
1620
- }
1621
- else
1622
- {
1623
- prev.next = node;
1624
- }
1625
- done = true;
1626
- }
1627
- else if ( y > node.y )
1628
- {
1629
- /* Head further up the LMT */
1630
- if( node.next == null )
1631
- {
1632
- node.next = new LmtNode(y);
1633
- node = node.next;
1634
- done = true;
1635
- }
1636
- else
1637
- {
1638
- prev = node;
1639
- node = node.next;
1640
- }
1641
- }
1642
- else
1643
- {
1644
- /* Use this existing LMT node */
1645
- done = true;
1646
- }
1647
- }
1648
- return node;
1422
+ }
1423
+
1424
+ if (op == OperationType.GPC_INT) {
1425
+ /* For each subject contour, search for any clip contour overlaps */
1426
+ for (int s = 0; s < subj_num_poly; s++) {
1427
+ boolean overlap = false;
1428
+ for (int c = 0; !overlap && (c < clip_num_poly); c++) {
1429
+ overlap = o_table[s][c];
1430
+ }
1431
+ if (!overlap) {
1432
+ subj.setContributing(s, false); // Flag non contributing status
1433
+ }
1649
1434
  }
1435
+ }
1650
1436
  }
1651
-
1652
- private static void insert_bound( LmtNode lmt_node, EdgeNode e)
1653
- {
1654
- if( lmt_node.first_bound == null )
1655
- {
1656
- /* Link node e to the tail of the list */
1657
- lmt_node.first_bound = e;
1658
- }
1659
- else
1660
- {
1661
- boolean done = false;
1662
- EdgeNode prev_bound = null;
1663
- EdgeNode current_bound = lmt_node.first_bound;
1664
- while( !done )
1665
- {
1666
- /* Do primary sort on the x field */
1667
- if (e.bot_x < current_bound.bot_x)
1668
- {
1669
- /* Insert a new node mid-list */
1670
- if( prev_bound == null )
1671
- {
1672
- lmt_node.first_bound = e;
1673
- }
1674
- else
1675
- {
1676
- prev_bound.next_bound = e;
1677
- }
1678
- e.next_bound = current_bound;
1679
-
1680
- done = true;
1681
- }
1682
- else if (e.bot_x == current_bound.bot_x)
1683
- {
1684
- /* Do secondary sort on the dx field */
1685
- if (e.dx < current_bound.dx)
1686
- {
1687
- /* Insert a new node mid-list */
1688
- if( prev_bound == null )
1689
- {
1690
- lmt_node.first_bound = e;
1691
- }
1692
- else
1693
- {
1694
- prev_bound.next_bound = e;
1695
- }
1696
- e.next_bound = current_bound;
1697
- done = true;
1698
- }
1699
- else
1700
- {
1701
- /* Head further down the list */
1702
- if( current_bound.next_bound == null )
1703
- {
1704
- current_bound.next_bound = e;
1705
- done = true;
1706
- }
1707
- else
1708
- {
1709
- prev_bound = current_bound;
1710
- current_bound = current_bound.next_bound;
1711
- }
1712
- }
1713
- }
1714
- else
1715
- {
1716
- /* Head further down the list */
1717
- if( current_bound.next_bound == null )
1718
- {
1719
- current_bound.next_bound = e;
1720
- done = true;
1721
- }
1722
- else
1723
- {
1724
- prev_bound = current_bound;
1725
- current_bound = current_bound.next_bound;
1726
- }
1727
- }
1437
+
1438
+ private static LmtNode bound_list(LmtTable lmt_table, float y) {
1439
+ if (lmt_table.top_node == null) {
1440
+ lmt_table.top_node = new LmtNode(y);
1441
+ return lmt_table.top_node;
1442
+ } else {
1443
+ LmtNode prev = null;
1444
+ LmtNode node = lmt_table.top_node;
1445
+ boolean done = false;
1446
+ while (!done) {
1447
+ if (y < node.y) {
1448
+ /* Insert a new LMT node before the current node */
1449
+ LmtNode existing_node = node;
1450
+ node = new LmtNode(y);
1451
+ node.next = existing_node;
1452
+ if (prev == null) {
1453
+ lmt_table.top_node = node;
1454
+ } else {
1455
+ prev.next = node;
1728
1456
  }
1457
+ done = true;
1458
+ } else if (y > node.y) {
1459
+ /* Head further up the LMT */
1460
+ if (node.next == null) {
1461
+ node.next = new LmtNode(y);
1462
+ node = node.next;
1463
+ done = true;
1464
+ } else {
1465
+ prev = node;
1466
+ node = node.next;
1467
+ }
1468
+ } else {
1469
+ /* Use this existing LMT node */
1470
+ done = true;
1471
+ }
1729
1472
  }
1473
+ return node;
1474
+ }
1730
1475
  }
1731
-
1732
- private static void add_edge_to_aet( AetTree aet , EdgeNode edge )
1733
- {
1734
- if ( aet.top_node == null )
1735
- {
1736
- /* Append edge onto the tail end of the AET */
1737
- aet.top_node = edge;
1738
- edge.prev = null;
1739
- edge.next= null;
1740
- }
1741
- else
1742
- {
1743
- EdgeNode current_edge = aet.top_node;
1744
- EdgeNode prev = null;
1745
- boolean done = false;
1746
- while( !done )
1747
- {
1748
- /* Do primary sort on the xb field */
1749
- if (edge.xb < current_edge.xb)
1750
- {
1751
- /* Insert edge here (before the AET edge) */
1752
- edge.prev= prev;
1753
- edge.next= current_edge;
1754
- current_edge.prev = edge;
1755
- if( prev == null )
1756
- {
1757
- aet.top_node = edge;
1758
- }
1759
- else
1760
- {
1761
- prev.next = edge;
1762
- }
1763
- done = true;
1764
- }
1765
- else if (edge.xb == current_edge.xb)
1766
- {
1767
- /* Do secondary sort on the dx field */
1768
- if (edge.dx < current_edge.dx)
1769
- {
1770
- /* Insert edge here (before the AET edge) */
1771
- edge.prev= prev;
1772
- edge.next= current_edge;
1773
- current_edge.prev = edge;
1774
- if( prev == null )
1775
- {
1776
- aet.top_node = edge;
1777
- }
1778
- else
1779
- {
1780
- prev.next = edge;
1781
- }
1782
- done = true;
1783
- }
1784
- else
1785
- {
1786
- /* Head further into the AET */
1787
- prev = current_edge;
1788
- if( current_edge.next == null )
1789
- {
1790
- current_edge.next = edge;
1791
- edge.prev = current_edge;
1792
- edge.next = null;
1793
- done = true;
1794
- }
1795
- else
1796
- {
1797
- current_edge = current_edge.next;
1798
- }
1799
- }
1800
- }
1801
- else
1802
- {
1803
- /* Head further into the AET */
1804
- prev = current_edge;
1805
- if( current_edge.next == null )
1806
- {
1807
- current_edge.next = edge;
1808
- edge.prev = current_edge;
1809
- edge.next = null;
1810
- done = true;
1811
- }
1812
- else
1813
- {
1814
- current_edge = current_edge.next;
1815
- }
1816
- }
1476
+
1477
+ private static void insert_bound(LmtNode lmt_node, EdgeNode e) {
1478
+ if (lmt_node.first_bound == null) {
1479
+ /* Link node e to the tail of the list */
1480
+ lmt_node.first_bound = e;
1481
+ } else {
1482
+ boolean done = false;
1483
+ EdgeNode prev_bound = null;
1484
+ EdgeNode current_bound = lmt_node.first_bound;
1485
+ while (!done) {
1486
+ /* Do primary sort on the x field */
1487
+ if (e.bot_x < current_bound.bot_x) {
1488
+ /* Insert a new node mid-list */
1489
+ if (prev_bound == null) {
1490
+ lmt_node.first_bound = e;
1491
+ } else {
1492
+ prev_bound.next_bound = e;
1493
+ }
1494
+ e.next_bound = current_bound;
1495
+
1496
+ done = true;
1497
+ } else if (e.bot_x == current_bound.bot_x) {
1498
+ /* Do secondary sort on the dx field */
1499
+ if (e.dx < current_bound.dx) {
1500
+ /* Insert a new node mid-list */
1501
+ if (prev_bound == null) {
1502
+ lmt_node.first_bound = e;
1503
+ } else {
1504
+ prev_bound.next_bound = e;
1505
+ }
1506
+ e.next_bound = current_bound;
1507
+ done = true;
1508
+ } else {
1509
+ /* Head further down the list */
1510
+ if (current_bound.next_bound == null) {
1511
+ current_bound.next_bound = e;
1512
+ done = true;
1513
+ } else {
1514
+ prev_bound = current_bound;
1515
+ current_bound = current_bound.next_bound;
1516
+ }
1817
1517
  }
1518
+ } else {
1519
+ /* Head further down the list */
1520
+ if (current_bound.next_bound == null) {
1521
+ current_bound.next_bound = e;
1522
+ done = true;
1523
+ } else {
1524
+ prev_bound = current_bound;
1525
+ current_bound = current_bound.next_bound;
1526
+ }
1527
+ }
1818
1528
  }
1529
+ }
1819
1530
  }
1820
-
1821
- private static void add_to_sbtree( ScanBeamTreeEntries sbte, float y )
1822
- {
1823
- if( sbte.sb_tree == null )
1824
- {
1825
- /* Add a new tree node here */
1826
- sbte.sb_tree = new ScanBeamTree( y );
1827
- sbte.sbt_entries++;
1828
- return;
1829
- }
1830
- ScanBeamTree tree_node = sbte.sb_tree;
1831
- boolean done = false;
1832
- while( !done )
1833
- {
1834
- if ( tree_node.y > y)
1835
- {
1836
- if( tree_node.less == null )
1837
- {
1838
- tree_node.less = new ScanBeamTree(y);
1839
- sbte.sbt_entries++;
1840
- done = true;
1841
- }
1842
- else
1843
- {
1844
- tree_node = tree_node.less;
1845
- }
1531
+
1532
+ private static void add_edge_to_aet(AetTree aet, EdgeNode edge) {
1533
+ if (aet.top_node == null) {
1534
+ /* Append edge onto the tail end of the AET */
1535
+ aet.top_node = edge;
1536
+ edge.prev = null;
1537
+ edge.next = null;
1538
+ } else {
1539
+ EdgeNode current_edge = aet.top_node;
1540
+ EdgeNode prev = null;
1541
+ boolean done = false;
1542
+ while (!done) {
1543
+ /* Do primary sort on the xb field */
1544
+ if (edge.xb < current_edge.xb) {
1545
+ /* Insert edge here (before the AET edge) */
1546
+ edge.prev = prev;
1547
+ edge.next = current_edge;
1548
+ current_edge.prev = edge;
1549
+ if (prev == null) {
1550
+ aet.top_node = edge;
1551
+ } else {
1552
+ prev.next = edge;
1846
1553
  }
1847
- else if ( tree_node.y < y)
1848
- {
1849
- if( tree_node.more == null )
1850
- {
1851
- tree_node.more = new ScanBeamTree(y);
1852
- sbte.sbt_entries++;
1853
- done = true;
1854
- }
1855
- else
1856
- {
1857
- tree_node = tree_node.more;
1858
- }
1554
+ done = true;
1555
+ } else if (edge.xb == current_edge.xb) {
1556
+ /* Do secondary sort on the dx field */
1557
+ if (edge.dx < current_edge.dx) {
1558
+ /* Insert edge here (before the AET edge) */
1559
+ edge.prev = prev;
1560
+ edge.next = current_edge;
1561
+ current_edge.prev = edge;
1562
+ if (prev == null) {
1563
+ aet.top_node = edge;
1564
+ } else {
1565
+ prev.next = edge;
1566
+ }
1567
+ done = true;
1568
+ } else {
1569
+ /* Head further into the AET */
1570
+ prev = current_edge;
1571
+ if (current_edge.next == null) {
1572
+ current_edge.next = edge;
1573
+ edge.prev = current_edge;
1574
+ edge.next = null;
1575
+ done = true;
1576
+ } else {
1577
+ current_edge = current_edge.next;
1578
+ }
1859
1579
  }
1860
- else
1861
- {
1580
+ } else {
1581
+ /* Head further into the AET */
1582
+ prev = current_edge;
1583
+ if (current_edge.next == null) {
1584
+ current_edge.next = edge;
1585
+ edge.prev = current_edge;
1586
+ edge.next = null;
1862
1587
  done = true;
1588
+ } else {
1589
+ current_edge = current_edge.next;
1863
1590
  }
1591
+ }
1864
1592
  }
1593
+ }
1865
1594
  }
1866
-
1867
- private static EdgeTable build_lmt( LmtTable lmt_table,
1868
- ScanBeamTreeEntries sbte,
1869
- RPolygon p,
1870
- int type, //poly type SUBJ/CLIP
1871
- OperationType op)
1872
- {
1595
+
1596
+ private static void add_to_sbtree(ScanBeamTreeEntries sbte, float y) {
1597
+ if (sbte.sb_tree == null) {
1598
+ /* Add a new tree node here */
1599
+ sbte.sb_tree = new ScanBeamTree(y);
1600
+ sbte.sbt_entries++;
1601
+ return;
1602
+ }
1603
+ ScanBeamTree tree_node = sbte.sb_tree;
1604
+ boolean done = false;
1605
+ while (!done) {
1606
+ if (tree_node.y > y) {
1607
+ if (tree_node.less == null) {
1608
+ tree_node.less = new ScanBeamTree(y);
1609
+ sbte.sbt_entries++;
1610
+ done = true;
1611
+ } else {
1612
+ tree_node = tree_node.less;
1613
+ }
1614
+ } else if (tree_node.y < y) {
1615
+ if (tree_node.more == null) {
1616
+ tree_node.more = new ScanBeamTree(y);
1617
+ sbte.sbt_entries++;
1618
+ done = true;
1619
+ } else {
1620
+ tree_node = tree_node.more;
1621
+ }
1622
+ } else {
1623
+ done = true;
1624
+ }
1625
+ }
1626
+ }
1627
+
1628
+ private static EdgeTable build_lmt(LmtTable lmt_table,
1629
+ ScanBeamTreeEntries sbte,
1630
+ RPolygon p,
1631
+ int type, //poly type SUBJ/CLIP
1632
+ OperationType op) {
1873
1633
  /* Create the entire input polygon edge table in one go */
1874
1634
  EdgeTable edge_table = new EdgeTable();
1875
-
1876
- for ( int c= 0; c < p.getNumInnerPoly(); c++)
1877
- {
1878
- RPolygon ip = p.getInnerPoly(c);
1879
- if( !ip.isContributing(0) )
1880
- {
1881
- /* Ignore the non-contributing contour */
1882
- ip.setContributing(0, true);
1635
+
1636
+ for (int c = 0; c < p.getNumInnerPoly(); c++) {
1637
+ RPolygon ip = p.getInnerPoly(c);
1638
+ if (!ip.isContributing(0)) {
1639
+ /* Ignore the non-contributing contour */
1640
+ ip.setContributing(0, true);
1641
+ } else {
1642
+ /* Perform contour optimisation */
1643
+ int num_vertices = 0;
1644
+ int e_index = 0;
1645
+ edge_table = new EdgeTable();
1646
+ for (int i = 0; i < ip.getNumPoints(); i++) {
1647
+ if (OPTIMAL(ip, i)) {
1648
+ float x = ip.getX(i);
1649
+ float y = ip.getY(i);
1650
+ edge_table.addNode(x, y);
1651
+
1652
+ /* Record vertex in the scanbeam table */
1653
+ add_to_sbtree(sbte, ip.getY(i));
1654
+
1655
+ num_vertices++;
1883
1656
  }
1884
- else
1885
- {
1886
- /* Perform contour optimisation */
1887
- int num_vertices= 0;
1888
- int e_index = 0;
1889
- edge_table = new EdgeTable();
1890
- for ( int i= 0; i < ip.getNumPoints(); i++)
1891
- {
1892
- if( OPTIMAL(ip, i) )
1893
- {
1894
- float x = ip.getX(i);
1895
- float y = ip.getY(i);
1896
- edge_table.addNode( x, y );
1897
-
1898
- /* Record vertex in the scanbeam table */
1899
- add_to_sbtree( sbte, ip.getY(i) );
1900
-
1901
- num_vertices++;
1902
- }
1903
- }
1904
-
1905
- /* Do the contour forward pass */
1906
- for ( int min= 0; min < num_vertices; min++)
1907
- {
1908
- /* If a forward local minimum... */
1909
- if( edge_table.FWD_MIN( min ) )
1910
- {
1911
- /* Search for the next local maximum... */
1912
- int num_edges = 1;
1913
- int max = NEXT_INDEX( min, num_vertices );
1914
- while( edge_table.NOT_FMAX( max ) )
1915
- {
1916
- num_edges++;
1917
- max = NEXT_INDEX( max, num_vertices );
1918
- }
1919
-
1920
- /* Build the next edge list */
1921
- int v = min;
1922
- EdgeNode e = edge_table.getNode( e_index );
1923
- e.bstate_below = BundleState.UNBUNDLED;
1924
- e.bundle_below_clip = 0;
1925
- e.bundle_below_subj = 0;
1926
-
1927
- for ( int i= 0; i < num_edges; i++)
1928
- {
1929
- EdgeNode ei = edge_table.getNode( e_index+i );
1930
- EdgeNode ev = edge_table.getNode( v );
1931
-
1932
- ei.xb = ev.vertex_x;
1933
- ei.bot_x = ev.vertex_x;
1934
- ei.bot_y = ev.vertex_y;
1935
-
1936
- v = NEXT_INDEX(v, num_vertices);
1937
- ev = edge_table.getNode( v );
1938
-
1939
- ei.top_x= ev.vertex_x;
1940
- ei.top_y= ev.vertex_y;
1941
- ei.dx= (ev.vertex_x - ei.bot_x) / (ei.top_y - ei.bot_y);
1942
- ei.type = type;
1943
- ei.outp_above = null;
1944
- ei.outp_below = null;
1945
- ei.next = null;
1946
- ei.prev = null;
1947
- ei.succ = ((num_edges > 1) && (i < (num_edges - 1))) ? edge_table.getNode(e_index+i+1) : null;
1948
- ei.pred = ((num_edges > 1) && (i > 0)) ? edge_table.getNode(e_index+i-1) : null;
1949
- ei.next_bound = null;
1950
- ei.bside_clip = (op == OperationType.GPC_DIFF) ? RIGHT : LEFT;
1951
- ei.bside_subj = LEFT;
1952
- }
1953
- insert_bound( bound_list(lmt_table, edge_table.getNode(min).vertex_y), e);
1954
- e_index += num_edges;
1955
- }
1956
- }
1957
-
1958
- /* Do the contour reverse pass */
1959
- for ( int min= 0; min < num_vertices; min++)
1960
- {
1961
- /* If a reverse local minimum... */
1962
- if ( edge_table.REV_MIN( min ) )
1963
- {
1964
- /* Search for the previous local maximum... */
1965
- int num_edges= 1;
1966
- int max = PREV_INDEX(min, num_vertices);
1967
- while( edge_table.NOT_RMAX( max ) )
1968
- {
1969
- num_edges++;
1970
- max = PREV_INDEX(max, num_vertices);
1971
- }
1972
-
1973
- /* Build the previous edge list */
1974
- int v = min;
1975
- EdgeNode e = edge_table.getNode( e_index );
1976
- e.bstate_below = BundleState.UNBUNDLED;
1977
- e.bundle_below_clip = 0;
1978
- e.bundle_below_subj = 0;
1979
-
1980
- for (int i= 0; i < num_edges; i++)
1981
- {
1982
- EdgeNode ei = edge_table.getNode( e_index+i );
1983
- EdgeNode ev = edge_table.getNode( v );
1984
-
1985
- ei.xb = ev.vertex_x;
1986
- ei.bot_x = ev.vertex_x;
1987
- ei.bot_y = ev.vertex_y;
1988
-
1989
- v= PREV_INDEX(v, num_vertices);
1990
- ev = edge_table.getNode( v );
1991
-
1992
- ei.top_x = ev.vertex_x;
1993
- ei.top_y = ev.vertex_y;
1994
- ei.dx = (ev.vertex_x - ei.bot_x) / (ei.top_y - ei.bot_y);
1995
- ei.type = type;
1996
- ei.outp_above = null;
1997
- ei.outp_below = null;
1998
- ei.next = null;
1999
- ei.prev = null;
2000
- ei.succ = ((num_edges > 1) && (i < (num_edges - 1))) ? edge_table.getNode(e_index+i+1) : null;
2001
- ei.pred = ((num_edges > 1) && (i > 0)) ? edge_table.getNode(e_index+i-1) : null;
2002
- ei.next_bound = null;
2003
- ei.bside_clip = (op == OperationType.GPC_DIFF) ? RIGHT : LEFT;
2004
- ei.bside_subj = LEFT;
2005
- }
2006
- insert_bound( bound_list(lmt_table, edge_table.getNode(min).vertex_y), e);
2007
- e_index+= num_edges;
2008
- }
2009
- }
1657
+ }
1658
+
1659
+ /* Do the contour forward pass */
1660
+ for (int min = 0; min < num_vertices; min++) {
1661
+ /* If a forward local minimum... */
1662
+ if (edge_table.FWD_MIN(min)) {
1663
+ /* Search for the next local maximum... */
1664
+ int num_edges = 1;
1665
+ int max = NEXT_INDEX(min, num_vertices);
1666
+ while (edge_table.NOT_FMAX(max)) {
1667
+ num_edges++;
1668
+ max = NEXT_INDEX(max, num_vertices);
1669
+ }
1670
+
1671
+ /* Build the next edge list */
1672
+ int v = min;
1673
+ EdgeNode e = edge_table.getNode(e_index);
1674
+ e.bstate_below = BundleState.UNBUNDLED;
1675
+ e.bundle_below_clip = 0;
1676
+ e.bundle_below_subj = 0;
1677
+
1678
+ for (int i = 0; i < num_edges; i++) {
1679
+ EdgeNode ei = edge_table.getNode(e_index + i);
1680
+ EdgeNode ev = edge_table.getNode(v);
1681
+
1682
+ ei.xb = ev.vertex_x;
1683
+ ei.bot_x = ev.vertex_x;
1684
+ ei.bot_y = ev.vertex_y;
1685
+
1686
+ v = NEXT_INDEX(v, num_vertices);
1687
+ ev = edge_table.getNode(v);
1688
+
1689
+ ei.top_x = ev.vertex_x;
1690
+ ei.top_y = ev.vertex_y;
1691
+ ei.dx = (ev.vertex_x - ei.bot_x) / (ei.top_y - ei.bot_y);
1692
+ ei.type = type;
1693
+ ei.outp_above = null;
1694
+ ei.outp_below = null;
1695
+ ei.next = null;
1696
+ ei.prev = null;
1697
+ ei.succ = ((num_edges > 1) && (i < (num_edges - 1))) ? edge_table.getNode(e_index + i + 1) : null;
1698
+ ei.pred = ((num_edges > 1) && (i > 0)) ? edge_table.getNode(e_index + i - 1) : null;
1699
+ ei.next_bound = null;
1700
+ ei.bside_clip = (op == OperationType.GPC_DIFF) ? RIGHT : LEFT;
1701
+ ei.bside_subj = LEFT;
1702
+ }
1703
+ insert_bound(bound_list(lmt_table, edge_table.getNode(min).vertex_y), e);
1704
+ e_index += num_edges;
1705
+ }
1706
+ }
1707
+
1708
+ /* Do the contour reverse pass */
1709
+ for (int min = 0; min < num_vertices; min++) {
1710
+ /* If a reverse local minimum... */
1711
+ if (edge_table.REV_MIN(min)) {
1712
+ /* Search for the previous local maximum... */
1713
+ int num_edges = 1;
1714
+ int max = PREV_INDEX(min, num_vertices);
1715
+ while (edge_table.NOT_RMAX(max)) {
1716
+ num_edges++;
1717
+ max = PREV_INDEX(max, num_vertices);
1718
+ }
1719
+
1720
+ /* Build the previous edge list */
1721
+ int v = min;
1722
+ EdgeNode e = edge_table.getNode(e_index);
1723
+ e.bstate_below = BundleState.UNBUNDLED;
1724
+ e.bundle_below_clip = 0;
1725
+ e.bundle_below_subj = 0;
1726
+
1727
+ for (int i = 0; i < num_edges; i++) {
1728
+ EdgeNode ei = edge_table.getNode(e_index + i);
1729
+ EdgeNode ev = edge_table.getNode(v);
1730
+
1731
+ ei.xb = ev.vertex_x;
1732
+ ei.bot_x = ev.vertex_x;
1733
+ ei.bot_y = ev.vertex_y;
1734
+
1735
+ v = PREV_INDEX(v, num_vertices);
1736
+ ev = edge_table.getNode(v);
1737
+
1738
+ ei.top_x = ev.vertex_x;
1739
+ ei.top_y = ev.vertex_y;
1740
+ ei.dx = (ev.vertex_x - ei.bot_x) / (ei.top_y - ei.bot_y);
1741
+ ei.type = type;
1742
+ ei.outp_above = null;
1743
+ ei.outp_below = null;
1744
+ ei.next = null;
1745
+ ei.prev = null;
1746
+ ei.succ = ((num_edges > 1) && (i < (num_edges - 1))) ? edge_table.getNode(e_index + i + 1) : null;
1747
+ ei.pred = ((num_edges > 1) && (i > 0)) ? edge_table.getNode(e_index + i - 1) : null;
1748
+ ei.next_bound = null;
1749
+ ei.bside_clip = (op == OperationType.GPC_DIFF) ? RIGHT : LEFT;
1750
+ ei.bside_subj = LEFT;
1751
+ }
1752
+ insert_bound(bound_list(lmt_table, edge_table.getNode(min).vertex_y), e);
1753
+ e_index += num_edges;
2010
1754
  }
1755
+ }
2011
1756
  }
1757
+ }
2012
1758
  return edge_table;
2013
1759
  }
2014
-
2015
- private static StNode add_st_edge( StNode st, ItNodeTable it, EdgeNode edge, float dy)
2016
- {
2017
- if (st == null)
2018
- {
2019
- /* Append edge onto the tail end of the ST */
2020
- st = new StNode( edge, null );
2021
- }
2022
- else
2023
- {
2024
- float den= (st.xt - st.xb) - (edge.xt - edge.xb);
2025
-
2026
- /* If new edge and ST edge don't cross */
2027
- if( (edge.xt >= st.xt) || (edge.dx == st.dx) || (Math.abs(den) <= GPC_EPSILON))
2028
- {
2029
- /* No intersection - insert edge here (before the ST edge) */
2030
- StNode existing_node = st;
2031
- st = new StNode( edge, existing_node );
2032
- }
2033
- else
2034
- {
2035
- /* Compute intersection between new edge and ST edge */
2036
- float r= (edge.xb - st.xb) / den;
2037
- float x= st.xb + r * (st.xt - st.xb);
2038
- float y= r * dy;
2039
-
2040
- /* Insert the edge pointers and the intersection point in the IT */
2041
- it.top_node = add_intersection(it.top_node, st.edge, edge, x, y);
2042
-
2043
- /* Head further into the ST */
2044
- st.prev = add_st_edge(st.prev, it, edge, dy);
2045
- }
1760
+
1761
+ private static StNode add_st_edge(StNode st, ItNodeTable it, EdgeNode edge, float dy) {
1762
+ if (st == null) {
1763
+ /* Append edge onto the tail end of the ST */
1764
+ st = new StNode(edge, null);
1765
+ } else {
1766
+ float den = (st.xt - st.xb) - (edge.xt - edge.xb);
1767
+
1768
+ /* If new edge and ST edge don't cross */
1769
+ if ((edge.xt >= st.xt) || (edge.dx == st.dx) || (Math.abs(den) <= GPC_EPSILON)) {
1770
+ /* No intersection - insert edge here (before the ST edge) */
1771
+ StNode existing_node = st;
1772
+ st = new StNode(edge, existing_node);
1773
+ } else {
1774
+ /* Compute intersection between new edge and ST edge */
1775
+ float r = (edge.xb - st.xb) / den;
1776
+ float x = st.xb + r * (st.xt - st.xb);
1777
+ float y = r * dy;
1778
+
1779
+ /* Insert the edge pointers and the intersection point in the IT */
1780
+ it.top_node = add_intersection(it.top_node, st.edge, edge, x, y);
1781
+
1782
+ /* Head further into the ST */
1783
+ st.prev = add_st_edge(st.prev, it, edge, dy);
2046
1784
  }
1785
+ }
2047
1786
  return st;
2048
1787
  }
2049
-
2050
- private static ItNode add_intersection( ItNode it_node,
2051
- EdgeNode edge0,
2052
- EdgeNode edge1,
2053
- float x,
2054
- float y)
2055
- {
2056
- if (it_node == null)
2057
- {
2058
- /* Append a new node to the tail of the list */
2059
- it_node = new ItNode( edge0, edge1, x, y, null );
2060
- }
2061
- else
2062
- {
2063
- if ( it_node.point_y > y)
2064
- {
2065
- /* Insert a new node mid-list */
2066
- ItNode existing_node = it_node;
2067
- it_node = new ItNode( edge0, edge1, x, y, existing_node );
2068
- }
2069
- else
2070
- {
2071
- /* Head further down the list */
2072
- it_node.next = add_intersection( it_node.next, edge0, edge1, x, y);
2073
- }
1788
+
1789
+ private static ItNode add_intersection(ItNode it_node,
1790
+ EdgeNode edge0,
1791
+ EdgeNode edge1,
1792
+ float x,
1793
+ float y) {
1794
+ if (it_node == null) {
1795
+ /* Append a new node to the tail of the list */
1796
+ it_node = new ItNode(edge0, edge1, x, y, null);
1797
+ } else {
1798
+ if (it_node.point_y > y) {
1799
+ /* Insert a new node mid-list */
1800
+ ItNode existing_node = it_node;
1801
+ it_node = new ItNode(edge0, edge1, x, y, existing_node);
1802
+ } else {
1803
+ /* Head further down the list */
1804
+ it_node.next = add_intersection(it_node.next, edge0, edge1, x, y);
2074
1805
  }
1806
+ }
2075
1807
  return it_node;
2076
1808
  }
2077
-
2078
- private static int count_tristrips(PolygonNode tn)
2079
- {
1809
+
1810
+ private static int count_tristrips(PolygonNode tn) {
2080
1811
  int total;
2081
-
2082
- for (total= 0; tn!=null; tn= tn.next)
2083
- {
2084
- if (tn.active > 2)
2085
- {
2086
- total++;
2087
- }
1812
+
1813
+ for (total = 0; tn != null; tn = tn.next) {
1814
+ if (tn.active > 2) {
1815
+ total++;
2088
1816
  }
1817
+ }
2089
1818
  return total;
2090
1819
  }
2091
-
2092
- private static VertexNode add_vertex(VertexNode ve_node, float x, float y)
2093
- {
2094
- if (ve_node == null)
2095
- {
2096
- /* Append a new node to the tail of the list */
2097
- ve_node = new VertexNode( x, y);
2098
- }
2099
- else
2100
- {
2101
- /* Head further down the list */
2102
- ve_node.next = add_vertex( ve_node.next, x, y);
2103
- }
1820
+
1821
+ private static VertexNode add_vertex(VertexNode ve_node, float x, float y) {
1822
+ if (ve_node == null) {
1823
+ /* Append a new node to the tail of the list */
1824
+ ve_node = new VertexNode(x, y);
1825
+ } else {
1826
+ /* Head further down the list */
1827
+ ve_node.next = add_vertex(ve_node.next, x, y);
1828
+ }
2104
1829
  return ve_node;
2105
1830
  }
2106
-
2107
- private static PolygonNode new_tristrip(PolygonNode po_node, EdgeNode edge, float x, float y)
2108
- {
2109
- if (po_node == null)
2110
- {
2111
- /* Append a new node to the tail of the list */
2112
- po_node = new PolygonNode();
2113
- po_node.v_left=add_vertex(po_node.v_left, x, y);
2114
- edge.outp_above= po_node;
2115
- }
2116
- else
2117
- {
2118
- /* Head further down the list */
2119
- po_node.next = new_tristrip( po_node.next, edge, x, y);
2120
- }
1831
+
1832
+ private static PolygonNode new_tristrip(PolygonNode po_node, EdgeNode edge, float x, float y) {
1833
+ if (po_node == null) {
1834
+ /* Append a new node to the tail of the list */
1835
+ po_node = new PolygonNode();
1836
+ po_node.v_left = add_vertex(po_node.v_left, x, y);
1837
+ edge.outp_above = po_node;
1838
+ } else {
1839
+ /* Head further down the list */
1840
+ po_node.next = new_tristrip(po_node.next, edge, x, y);
1841
+ }
2121
1842
  return po_node;
2122
1843
  }
2123
-
1844
+
2124
1845
  // ---------------------
2125
1846
  // --- Inner Classes ---
2126
1847
  // ---------------------
2127
-
2128
1848
  /**
2129
1849
  * Edge intersection classes
2130
1850
  */
2131
- private static class VertexType
2132
- {
2133
- public static final int NUL = 0; /* Empty non-intersection */
2134
- public static final int EMX = 1; /* External maximum */
2135
- public static final int ELI = 2; /* External left intermediate */
2136
- public static final int TED = 3; /* Top edge */
2137
- public static final int ERI = 4; /* External right intermediate */
2138
- public static final int RED = 5; /* Right edge */
2139
- public static final int IMM = 6; /* Internal maximum and minimum */
2140
- public static final int IMN = 7; /* Internal minimum */
2141
- public static final int EMN = 8; /* External minimum */
2142
- public static final int EMM = 9; /* External maximum and minimum */
2143
- public static final int LED = 10; /* Left edge */
2144
- public static final int ILI = 11; /* Internal left intermediate */
2145
- public static final int BED = 12; /* Bottom edge */
2146
- public static final int IRI = 13; /* Internal right intermediate */
2147
- public static final int IMX = 14; /* Internal maximum */
2148
- public static final int FUL = 15; /* Full non-intersection */
2149
-
2150
- public static int getType( int tr, int tl, int br, int bl )
2151
- {
1851
+ private static class VertexType {
1852
+
1853
+ public static final int NUL = 0;
1854
+ /* Empty non-intersection */
1855
+ public static final int EMX = 1;
1856
+ /* External maximum */
1857
+ public static final int ELI = 2;
1858
+ /* External left intermediate */
1859
+ public static final int TED = 3;
1860
+ /* Top edge */
1861
+ public static final int ERI = 4;
1862
+ /* External right intermediate */
1863
+ public static final int RED = 5;
1864
+ /* Right edge */
1865
+ public static final int IMM = 6;
1866
+ /* Internal maximum and minimum */
1867
+ public static final int IMN = 7;
1868
+ /* Internal minimum */
1869
+ public static final int EMN = 8;
1870
+ /* External minimum */
1871
+ public static final int EMM = 9;
1872
+ /* External maximum and minimum */
1873
+ public static final int LED = 10;
1874
+ /* Left edge */
1875
+ public static final int ILI = 11;
1876
+ /* Internal left intermediate */
1877
+ public static final int BED = 12;
1878
+ /* Bottom edge */
1879
+ public static final int IRI = 13;
1880
+ /* Internal right intermediate */
1881
+ public static final int IMX = 14;
1882
+ /* Internal maximum */
1883
+ public static final int FUL = 15;
1884
+
1885
+ /* Full non-intersection */
1886
+ public static int getType(int tr, int tl, int br, int bl) {
2152
1887
  return tr + (tl << 1) + (br << 2) + (bl << 3);
2153
1888
  }
2154
1889
  }
2155
-
1890
+
2156
1891
  /**
2157
- * Horizontal edge states
1892
+ * Horizontal edge states
2158
1893
  */
2159
- private static class HState
2160
- {
2161
- public static final int NH = 0; /* No horizontal edge */
2162
- public static final int BH = 1; /* Bottom horizontal edge */
2163
- public static final int TH = 2; /* Top horizontal edge */
2164
-
2165
- /* Horizontal edge state transitions within scanbeam boundary */
2166
- public static final int[][] next_h_state =
2167
- {
1894
+ private static class HState {
1895
+
1896
+ public static final int NH = 0;
1897
+ /* No horizontal edge */
1898
+ public static final int BH = 1;
1899
+ /* Bottom horizontal edge */
1900
+ public static final int TH = 2;
1901
+ /* Top horizontal edge */
1902
+
1903
+ /* Horizontal edge state transitions within scanbeam boundary */
1904
+ public static final int[][] NEXT_H_STATE
1905
+ = {
2168
1906
  /* ABOVE BELOW CROSS */
2169
- /* L R L R L R */
2170
- /* NH */ {BH, TH, TH, BH, NH, NH},
2171
- /* BH */ {NH, NH, NH, NH, TH, TH},
2172
- /* TH */ {NH, NH, NH, NH, BH, BH}
1907
+ /* L R L R L R */
1908
+ /* NH */{BH, TH, TH, BH, NH, NH},
1909
+ /* BH */ {NH, NH, NH, NH, TH, TH},
1910
+ /* TH */ {NH, NH, NH, NH, BH, BH}
2173
1911
  };
2174
1912
  }
2175
-
1913
+
2176
1914
  /**
2177
- * Edge bundle state
1915
+ * Edge bundle state
2178
1916
  */
2179
- private static class BundleState
2180
- {
1917
+ private static class BundleState {
1918
+
2181
1919
  private String state;
2182
- private BundleState( String state ) { this.state = state; }
2183
-
2184
- public static final BundleState UNBUNDLED = new BundleState( "UNBUNDLED" ); // Isolated edge not within a bundle
2185
- public static final BundleState BUNDLE_HEAD = new BundleState( "BUNDLE_HEAD" ); // Bundle head node
2186
- public static final BundleState BUNDLE_TAIL = new BundleState( "BUNDLE_TAIL" ); // Passive bundle tail node
2187
-
1920
+
1921
+ private BundleState(String state) {
1922
+ this.state = state;
1923
+ }
1924
+
1925
+ public static final BundleState UNBUNDLED = new BundleState("UNBUNDLED"); // Isolated edge not within a bundle
1926
+ public static final BundleState BUNDLE_HEAD = new BundleState("BUNDLE_HEAD"); // Bundle head node
1927
+ public static final BundleState BUNDLE_TAIL = new BundleState("BUNDLE_TAIL"); // Passive bundle tail node
1928
+
2188
1929
  @Override
2189
- public String toString() { return state; }
1930
+ public String toString() {
1931
+ return state;
1932
+ }
2190
1933
  }
2191
-
1934
+
2192
1935
  /**
2193
1936
  * Internal vertex list datatype
2194
1937
  */
2195
- private static class VertexNode
2196
- {
2197
- float x; // X coordinate component
2198
- float y; // Y coordinate component
1938
+ private static class VertexNode {
1939
+
1940
+ float x; // X coordinate component
1941
+ float y; // Y coordinate component
2199
1942
  VertexNode next; // Pointer to next vertex in list
2200
-
2201
- public VertexNode( float x, float y )
2202
- {
1943
+
1944
+ public VertexNode(float x, float y) {
2203
1945
  this.x = x;
2204
1946
  this.y = y;
2205
1947
  this.next = null;
2206
1948
  }
2207
1949
  }
2208
-
1950
+
2209
1951
  /**
2210
1952
  * Internal contour / tristrip type
2211
1953
  */
2212
- private static class PolygonNode
2213
- {
2214
- int active; /* Active flag / vertex count */
2215
- boolean hole; /* Hole / external contour flag */
2216
- VertexNode v_right, v_left; /* Left and right vertex list ptrs */
2217
- PolygonNode next; /* Pointer to next polygon contour */
2218
- PolygonNode proxy; /* Pointer to actual structure used */
2219
-
2220
- public PolygonNode()
2221
- {
1954
+ private static class PolygonNode {
1955
+
1956
+ int active;
1957
+ /* Active flag / vertex count */
1958
+ boolean hole;
1959
+ /* Hole / external contour flag */
1960
+ VertexNode v_right, v_left;
1961
+ /* Left and right vertex list ptrs */
1962
+ PolygonNode next;
1963
+ /* Pointer to next polygon contour */
1964
+ PolygonNode proxy;
1965
+
1966
+ /* Pointer to actual structure used */
1967
+ public PolygonNode() {
2222
1968
  this.v_left = null;
2223
1969
  this.v_right = null;
2224
1970
  this.next = null;
2225
- this.proxy = this; /* Initialise proxy to point to p itself */
1971
+ this.proxy = this;
1972
+ /* Initialise proxy to point to p itself */
2226
1973
  this.active = 1; //TRUE
2227
1974
  }
2228
-
2229
- public PolygonNode( PolygonNode next, float x, float y )
2230
- {
2231
- VertexNode vn = new VertexNode( x, y );
1975
+
1976
+ public PolygonNode(PolygonNode next, float x, float y) {
1977
+ VertexNode vn = new VertexNode(x, y);
2232
1978
  this.v_left = vn;
2233
1979
  this.v_right = vn;
2234
-
1980
+
2235
1981
  this.next = next;
2236
- this.proxy = this; /* Initialise proxy to point to p itself */
1982
+ this.proxy = this;
1983
+ /* Initialise proxy to point to p itself */
2237
1984
  this.active = 1; //TRUE
2238
1985
  }
2239
-
2240
- public void add_right( float x, float y )
2241
- {
2242
- VertexNode nv = new VertexNode( x, y );
2243
-
1986
+
1987
+ public void add_right(float x, float y) {
1988
+ VertexNode nv = new VertexNode(x, y);
1989
+
2244
1990
  /* Add vertex nv to the right end of the polygon's vertex list */
2245
- proxy.v_right.next= nv;
2246
-
1991
+ proxy.v_right.next = nv;
1992
+
2247
1993
  /* Update proxy->v[RIGHT] to point to nv */
2248
- proxy.v_right= nv;
1994
+ proxy.v_right = nv;
2249
1995
  }
2250
-
2251
- public void add_left( float x, float y)
2252
- {
2253
- VertexNode nv = new VertexNode( x, y );
2254
-
1996
+
1997
+ public void add_left(float x, float y) {
1998
+ VertexNode nv = new VertexNode(x, y);
1999
+
2255
2000
  /* Add vertex nv to the left end of the polygon's vertex list */
2256
- nv.next= proxy.v_left;
2257
-
2001
+ nv.next = proxy.v_left;
2002
+
2258
2003
  /* Update proxy->[LEFT] to point to nv */
2259
- proxy.v_left= nv;
2004
+ proxy.v_left = nv;
2260
2005
  }
2261
-
2006
+
2262
2007
  }
2263
-
2264
- private static class TopPolygonNode
2265
- {
2008
+
2009
+ private static class TopPolygonNode {
2010
+
2266
2011
  PolygonNode top_node = null;
2267
-
2268
- public PolygonNode add_local_min( float x, float y )
2269
- {
2012
+
2013
+ public PolygonNode add_local_min(float x, float y) {
2270
2014
  PolygonNode existing_min = top_node;
2271
-
2272
- top_node = new PolygonNode( existing_min, x, y );
2273
-
2015
+
2016
+ top_node = new PolygonNode(existing_min, x, y);
2017
+
2274
2018
  return top_node;
2275
2019
  }
2276
-
2277
- public void merge_left( PolygonNode p, PolygonNode q )
2278
- {
2020
+
2021
+ public void merge_left(PolygonNode p, PolygonNode q) {
2279
2022
  /* Label contour as a hole */
2280
2023
  q.proxy.hole = true;
2281
-
2282
- if (p.proxy != q.proxy)
2283
- {
2284
- /* Assign p's vertex list to the left end of q's list */
2285
- p.proxy.v_right.next= q.proxy.v_left;
2286
- q.proxy.v_left= p.proxy.v_left;
2287
-
2288
- /* Redirect any p.proxy references to q.proxy */
2289
- PolygonNode target = p.proxy;
2290
- for(PolygonNode node = top_node; (node != null); node = node.next)
2291
- {
2292
- if (node.proxy == target)
2293
- {
2294
- node.active= 0;
2295
- node.proxy= q.proxy;
2296
- }
2297
- }
2024
+
2025
+ if (p.proxy != q.proxy) {
2026
+ /* Assign p's vertex list to the left end of q's list */
2027
+ p.proxy.v_right.next = q.proxy.v_left;
2028
+ q.proxy.v_left = p.proxy.v_left;
2029
+
2030
+ /* Redirect any p.proxy references to q.proxy */
2031
+ PolygonNode target = p.proxy;
2032
+ for (PolygonNode node = top_node; (node != null); node = node.next) {
2033
+ if (node.proxy == target) {
2034
+ node.active = 0;
2035
+ node.proxy = q.proxy;
2036
+ }
2298
2037
  }
2038
+ }
2299
2039
  }
2300
-
2301
- public void merge_right( PolygonNode p, PolygonNode q )
2302
- {
2040
+
2041
+ public void merge_right(PolygonNode p, PolygonNode q) {
2303
2042
  /* Label contour as external */
2304
2043
  q.proxy.hole = false;
2305
-
2306
- if (p.proxy != q.proxy)
2307
- {
2308
- /* Assign p's vertex list to the right end of q's list */
2309
- q.proxy.v_right.next= p.proxy.v_left;
2310
- q.proxy.v_right= p.proxy.v_right;
2311
-
2312
- /* Redirect any p->proxy references to q->proxy */
2313
- PolygonNode target = p.proxy;
2314
- for (PolygonNode node = top_node; (node != null ); node = node.next)
2315
- {
2316
- if (node.proxy == target)
2317
- {
2318
- node.active = 0;
2319
- node.proxy= q.proxy;
2320
- }
2321
- }
2044
+
2045
+ if (p.proxy != q.proxy) {
2046
+ /* Assign p's vertex list to the right end of q's list */
2047
+ q.proxy.v_right.next = p.proxy.v_left;
2048
+ q.proxy.v_right = p.proxy.v_right;
2049
+
2050
+ /* Redirect any p->proxy references to q->proxy */
2051
+ PolygonNode target = p.proxy;
2052
+ for (PolygonNode node = top_node; (node != null); node = node.next) {
2053
+ if (node.proxy == target) {
2054
+ node.active = 0;
2055
+ node.proxy = q.proxy;
2056
+ }
2322
2057
  }
2058
+ }
2323
2059
  }
2324
-
2325
- public int count_contours()
2326
- {
2060
+
2061
+ public int count_contours() {
2327
2062
  int nc = 0;
2328
- for ( PolygonNode polygon = top_node; (polygon != null); polygon = polygon.next)
2329
- {
2330
- if (polygon.active != 0)
2331
- {
2332
- /* Count the vertices in the current contour */
2333
- int nv= 0;
2334
- for (VertexNode v= polygon.proxy.v_left; (v != null); v = v.next)
2335
- {
2336
- nv++;
2337
- }
2338
-
2339
- /* Record valid vertex counts in the active field */
2340
- if (nv > 2)
2341
- {
2342
- polygon.active = nv;
2343
- nc++;
2344
- }
2345
- else
2346
- {
2347
- /* Invalid contour: just free the heap */
2348
- // VertexNode nextv = null;
2349
- // for (VertexNode v= polygon.proxy.v_left; (v != null); v = nextv)
2350
- // {
2351
- // nextv= v.next;
2352
- // v = null;
2353
- // }
2354
- polygon.active= 0;
2355
- }
2356
- }
2063
+ for (PolygonNode polygon = top_node; (polygon != null); polygon = polygon.next) {
2064
+ if (polygon.active != 0) {
2065
+ /* Count the vertices in the current contour */
2066
+ int nv = 0;
2067
+ for (VertexNode v = polygon.proxy.v_left; (v != null); v = v.next) {
2068
+ nv++;
2069
+ }
2070
+
2071
+ /* Record valid vertex counts in the active field */
2072
+ if (nv > 2) {
2073
+ polygon.active = nv;
2074
+ nc++;
2075
+ } else {
2076
+ /* Invalid contour: just free the heap */
2077
+ // VertexNode nextv = null;
2078
+ // for (VertexNode v= polygon.proxy.v_left; (v != null); v = nextv)
2079
+ // {
2080
+ // nextv= v.next;
2081
+ // v = null;
2082
+ // }
2083
+ polygon.active = 0;
2084
+ }
2357
2085
  }
2086
+ }
2358
2087
  return nc;
2359
2088
  }
2360
-
2361
- public RPolygon getResult( Class polyClass )
2362
- {
2089
+
2090
+ public RPolygon getResult(Class polyClass) {
2363
2091
  //RPolygon result = createNewPoly( polyClass );
2364
2092
  RPolygon result = new RPolygon();
2365
2093
  int num_contours = count_contours();
2366
- if (num_contours > 0)
2367
- {
2368
- int c= 0;
2369
- PolygonNode npoly_node = null;
2370
- for (PolygonNode poly_node= top_node; (poly_node != null); poly_node = npoly_node)
2371
- {
2372
- npoly_node = poly_node.next;
2373
- if (poly_node.active != 0)
2374
- {
2375
- RContour contour;
2376
- if(result.countContours()>0){
2377
- contour = result.contours[0];
2378
- }else{
2379
- contour = new RContour();
2380
- }
2381
- //RPolygon poly = result;
2382
- if( num_contours > 0 )
2383
- {
2384
- contour = new RContour();
2385
- //poly = createNewPoly( polyClass );
2386
- }
2387
- if( poly_node.proxy.hole )
2388
- {
2389
- contour.isHole = poly_node.proxy.hole;
2390
- //poly.setIsHole( poly_node.proxy.hole );
2391
- }
2392
-
2393
- // ------------------------------------------------------------------------
2394
- // --- This algorithm puts the verticies into the poly in reverse order ---
2395
- // ------------------------------------------------------------------------
2396
- for (VertexNode vtx = poly_node.proxy.v_left; (vtx != null); vtx = vtx.next )
2397
- {
2398
- contour.addPoint(vtx.x, vtx.y);
2399
- //poly.add( vtx.x, vtx.y );
2400
- }
2401
- if( num_contours > 0 )
2402
- {
2403
- result.addContour(contour);
2404
- //result.add( poly );
2405
- }
2406
- c++;
2407
- }
2094
+ if (num_contours > 0) {
2095
+ int c = 0;
2096
+ PolygonNode npoly_node;
2097
+ for (PolygonNode poly_node = top_node; (poly_node != null); poly_node = npoly_node) {
2098
+ npoly_node = poly_node.next;
2099
+ if (poly_node.active != 0) {
2100
+ RContour contour;
2101
+ if (result.countContours() > 0) {
2102
+ contour = result.contours[0];
2103
+ } else {
2104
+ contour = new RContour();
2408
2105
  }
2409
-
2410
- // -----------------------------------------
2411
- // --- Sort holes to the end of the list ---
2412
- // -----------------------------------------
2413
- RPolygon orig = new RPolygon(result);
2414
- result = new RPolygon();
2415
- //result = createNewPoly( polyClass );
2416
- for( int i = 0; i < orig.countContours(); i++ )
2417
- //for( int i = 0; i < orig.getNumInnerPoly(); i++ )
2418
- {
2419
- RContour inner = orig.contours[i];
2420
- //RPolygon inner = orig.getInnerPoly(i);
2421
- if( !inner.isHole() )
2422
- {
2423
- result.addContour(inner);
2424
- //result.add(inner);
2425
- }
2106
+ //RPolygon poly = result;
2107
+ if (num_contours > 0) {
2108
+ contour = new RContour();
2109
+ //poly = createNewPoly( polyClass );
2426
2110
  }
2427
-
2428
- for( int i = 0; i < orig.countContours(); i++ )
2429
- //for( int i = 0; i < orig.getNumInnerPoly(); i++ )
2430
- {
2431
- RContour inner = orig.contours[i];
2432
- //RPolygon inner = orig.getInnerPoly(i);
2433
- if( inner.isHole() )
2434
- {
2435
- result.addContour(inner);
2436
- }
2111
+ if (poly_node.proxy.hole) {
2112
+ contour.isHole = poly_node.proxy.hole;
2113
+ //poly.setIsHole( poly_node.proxy.hole );
2114
+ }
2115
+
2116
+ // ------------------------------------------------------------------------
2117
+ // --- This algorithm puts the verticies into the poly in reverse order ---
2118
+ // ------------------------------------------------------------------------
2119
+ for (VertexNode vtx = poly_node.proxy.v_left; (vtx != null); vtx = vtx.next) {
2120
+ contour.addPoint(vtx.x, vtx.y);
2121
+ //poly.add( vtx.x, vtx.y );
2437
2122
  }
2123
+ if (num_contours > 0) {
2124
+ result.addContour(contour);
2125
+ //result.add( poly );
2126
+ }
2127
+ c++;
2128
+ }
2129
+ }
2130
+
2131
+ // -----------------------------------------
2132
+ // --- Sort holes to the end of the list ---
2133
+ // -----------------------------------------
2134
+ RPolygon orig = new RPolygon(result);
2135
+ result = new RPolygon();
2136
+ //result = createNewPoly( polyClass );
2137
+ for (int i = 0; i < orig.countContours(); i++) //for( int i = 0; i < orig.getNumInnerPoly(); i++ )
2138
+ {
2139
+ RContour inner = orig.contours[i];
2140
+ //RPolygon inner = orig.getInnerPoly(i);
2141
+ if (!inner.isHole()) {
2142
+ result.addContour(inner);
2143
+ //result.add(inner);
2144
+ }
2145
+ }
2146
+
2147
+ for (int i = 0; i < orig.countContours(); i++) //for( int i = 0; i < orig.getNumInnerPoly(); i++ )
2148
+ {
2149
+ RContour inner = orig.contours[i];
2150
+ //RPolygon inner = orig.getInnerPoly(i);
2151
+ if (inner.isHole()) {
2152
+ result.addContour(inner);
2153
+ }
2438
2154
  }
2155
+ }
2439
2156
  return result;
2440
2157
  }
2441
-
2442
- public void print()
2443
- {
2158
+
2159
+ public void print() {
2444
2160
  System.out.println("---- out_poly ----");
2445
- int c= 0;
2446
- PolygonNode npoly_node = null;
2447
- for (PolygonNode poly_node= top_node; (poly_node != null); poly_node = npoly_node)
2448
- {
2449
- System.out.println("contour="+c+" active="+poly_node.active+" hole="+poly_node.proxy.hole);
2450
- npoly_node = poly_node.next;
2451
- if (poly_node.active != 0)
2452
- {
2453
- int v=0;
2454
- for (VertexNode vtx = poly_node.proxy.v_left; (vtx != null); vtx = vtx.next )
2455
- {
2456
- System.out.println("v="+v+" vtx.x="+vtx.x+" vtx.y="+vtx.y);
2457
- }
2458
- c++;
2459
- }
2161
+ int c = 0;
2162
+ PolygonNode npoly_node;
2163
+ for (PolygonNode poly_node = top_node; (poly_node != null); poly_node = npoly_node) {
2164
+ System.out.println("contour=" + c + " active=" + poly_node.active + " hole=" + poly_node.proxy.hole);
2165
+ npoly_node = poly_node.next;
2166
+ if (poly_node.active != 0) {
2167
+ int v = 0;
2168
+ for (VertexNode vtx = poly_node.proxy.v_left; (vtx != null); vtx = vtx.next) {
2169
+ System.out.println("v=" + v + " vtx.x=" + vtx.x + " vtx.y=" + vtx.y);
2170
+ }
2171
+ c++;
2460
2172
  }
2461
- }
2173
+ }
2174
+ }
2462
2175
  }
2463
-
2464
- private static class EdgeNode
2465
- {
2466
- float vertex_x, vertex_y; /* Piggy-backed contour vertex data */
2467
- float bot_x, bot_y; /* Edge lower (x, y) coordinate */
2468
- float top_x, top_y; /* Edge upper (x, y) coordinate */
2469
- float xb; /* Scanbeam bottom x coordinate */
2470
- float xt; /* Scanbeam top x coordinate */
2471
- float dx; /* Change in x for a unit y increase */
2472
- int type; /* Clip / subject edge flag */
2176
+
2177
+ private static class EdgeNode {
2178
+
2179
+ float vertex_x, vertex_y;
2180
+ /* Piggy-backed contour vertex data */
2181
+ float bot_x, bot_y;
2182
+ /* Edge lower (x, y) coordinate */
2183
+ float top_x, top_y;
2184
+ /* Edge upper (x, y) coordinate */
2185
+ float xb;
2186
+ /* Scanbeam bottom x coordinate */
2187
+ float xt;
2188
+ /* Scanbeam top x coordinate */
2189
+ float dx;
2190
+ /* Change in x for a unit y increase */
2191
+ int type;
2192
+ /* Clip / subject edge flag */
2473
2193
  //int[][] bundle = new int[2][2]; /* Bundle edge flags */
2474
2194
  int[] bundle_above = new int[2];
2475
2195
  int bundle_below_clip, bundle_below_subj;
2476
-
2196
+
2477
2197
  //int[] bside = new int[2]; /* Bundle left / right indicators */
2478
- int bside_clip, bside_subj; /* Bundle left / right indicators */
2198
+ int bside_clip, bside_subj;
2199
+ /* Bundle left / right indicators */
2479
2200
  //BundleState[] bstate = new BundleState[2]; /* Edge bundle state */
2480
2201
  BundleState bstate_above, bstate_below;
2481
- PolygonNode outp_above, outp_below; /* Output polygon / tristrip pointer */
2482
- EdgeNode prev; /* Previous edge in the AET */
2483
- EdgeNode next; /* Next edge in the AET */
2484
- EdgeNode pred; /* Edge connected at the lower end */
2485
- EdgeNode succ; /* Edge connected at the upper end */
2486
- EdgeNode next_bound; /* Pointer to next bound in LMT */
2202
+ PolygonNode outp_above, outp_below;
2203
+ /* Output polygon / tristrip pointer */
2204
+ EdgeNode prev;
2205
+ /* Previous edge in the AET */
2206
+ EdgeNode next;
2207
+ /* Next edge in the AET */
2208
+ EdgeNode pred;
2209
+ /* Edge connected at the lower end */
2210
+ EdgeNode succ;
2211
+ /* Edge connected at the upper end */
2212
+ EdgeNode next_bound;
2213
+ /* Pointer to next bound in LMT */
2487
2214
  }
2488
-
2489
- private static class AetTree
2490
- {
2215
+
2216
+ private static class AetTree {
2217
+
2491
2218
  EdgeNode top_node;
2492
-
2493
- public void print()
2494
- {
2219
+
2220
+ public void print() {
2495
2221
  System.out.println("");
2496
2222
  System.out.println("aet");
2497
- for( EdgeNode edge = top_node; (edge != null); edge = edge.next )
2498
- {
2499
- System.out.println("edge.vertex_x="+edge.vertex_x+" edge.vertex_y="+edge.vertex_y);
2500
- }
2223
+ for (EdgeNode edge = top_node; (edge != null); edge = edge.next) {
2224
+ System.out.println("edge.vertex_x=" + edge.vertex_x + " edge.vertex_y=" + edge.vertex_y);
2225
+ }
2501
2226
  }
2502
2227
  }
2503
-
2504
- private static class EdgeTable
2505
- {
2228
+
2229
+ private static class EdgeTable {
2230
+
2506
2231
  private final List<EdgeNode> edges = new ArrayList<>();
2507
-
2508
- public void addNode( float x, float y )
2509
- {
2232
+
2233
+ public void addNode(float x, float y) {
2510
2234
  EdgeNode node = new EdgeNode();
2511
2235
  node.vertex_x = x;
2512
2236
  node.vertex_y = y;
2513
- edges.add( node );
2514
- }
2515
-
2516
- public EdgeNode getNode( int index )
2517
- {
2518
- return (EdgeNode)edges.get(index);
2519
- }
2520
-
2521
- public boolean FWD_MIN( int i )
2522
- {
2523
- EdgeNode prev = (EdgeNode)edges.get(PREV_INDEX(i, edges.size()));
2524
- EdgeNode next = (EdgeNode)edges.get(NEXT_INDEX(i, edges.size()));
2525
- EdgeNode ith = (EdgeNode)edges.get(i);
2526
- return ((prev.vertex_y >= ith.vertex_y) &&
2527
- (next.vertex_y > ith.vertex_y));
2528
- }
2529
-
2530
- public boolean NOT_FMAX( int i )
2531
- {
2532
- EdgeNode next = (EdgeNode)edges.get(NEXT_INDEX(i, edges.size()));
2533
- EdgeNode ith = (EdgeNode)edges.get(i);
2534
- return(next.vertex_y > ith.vertex_y);
2535
- }
2536
-
2537
- public boolean REV_MIN( int i )
2538
- {
2539
- EdgeNode prev = (EdgeNode)edges.get(PREV_INDEX(i, edges.size()));
2540
- EdgeNode next = (EdgeNode)edges.get(NEXT_INDEX(i, edges.size()));
2541
- EdgeNode ith = (EdgeNode)edges.get(i);
2542
- return ((prev.vertex_y > ith.vertex_y) &&
2543
- (next.vertex_y >= ith.vertex_y));
2544
- }
2545
-
2546
- public boolean NOT_RMAX( int i )
2547
- {
2548
- EdgeNode prev = (EdgeNode)edges.get(PREV_INDEX(i, edges.size()));
2549
- EdgeNode ith = (EdgeNode)edges.get(i);
2237
+ edges.add(node);
2238
+ }
2239
+
2240
+ public EdgeNode getNode(int index) {
2241
+ return (EdgeNode) edges.get(index);
2242
+ }
2243
+
2244
+ public boolean FWD_MIN(int i) {
2245
+ EdgeNode prev = (EdgeNode) edges.get(PREV_INDEX(i, edges.size()));
2246
+ EdgeNode next = (EdgeNode) edges.get(NEXT_INDEX(i, edges.size()));
2247
+ EdgeNode ith = (EdgeNode) edges.get(i);
2248
+ return ((prev.vertex_y >= ith.vertex_y)
2249
+ && (next.vertex_y > ith.vertex_y));
2250
+ }
2251
+
2252
+ public boolean NOT_FMAX(int i) {
2253
+ EdgeNode next = (EdgeNode) edges.get(NEXT_INDEX(i, edges.size()));
2254
+ EdgeNode ith = (EdgeNode) edges.get(i);
2255
+ return (next.vertex_y > ith.vertex_y);
2256
+ }
2257
+
2258
+ public boolean REV_MIN(int i) {
2259
+ EdgeNode prev = (EdgeNode) edges.get(PREV_INDEX(i, edges.size()));
2260
+ EdgeNode next = (EdgeNode) edges.get(NEXT_INDEX(i, edges.size()));
2261
+ EdgeNode ith = (EdgeNode) edges.get(i);
2262
+ return ((prev.vertex_y > ith.vertex_y)
2263
+ && (next.vertex_y >= ith.vertex_y));
2264
+ }
2265
+
2266
+ public boolean NOT_RMAX(int i) {
2267
+ EdgeNode prev = (EdgeNode) edges.get(PREV_INDEX(i, edges.size()));
2268
+ EdgeNode ith = (EdgeNode) edges.get(i);
2550
2269
  return (prev.vertex_y > ith.vertex_y);
2551
2270
  }
2552
2271
  }
2553
-
2272
+
2554
2273
  /**
2555
2274
  * Local minima table
2556
2275
  */
2557
- private static class LmtNode
2558
- {
2559
- float y; /* Y coordinate at local minimum */
2560
- EdgeNode first_bound; /* Pointer to bound list */
2561
- LmtNode next; /* Pointer to next local minimum */
2562
-
2563
- public LmtNode( float yvalue )
2564
- {
2276
+ private static class LmtNode {
2277
+
2278
+ float y;
2279
+ /* Y coordinate at local minimum */
2280
+ EdgeNode first_bound;
2281
+ /* Pointer to bound list */
2282
+ LmtNode next;
2283
+
2284
+ /* Pointer to next local minimum */
2285
+ public LmtNode(float yvalue) {
2565
2286
  y = yvalue;
2566
2287
  }
2567
2288
  }
2568
-
2569
- private static class LmtTable
2570
- {
2289
+
2290
+ private static class LmtTable {
2291
+
2571
2292
  LmtNode top_node;
2572
-
2573
- public void print()
2574
- {
2293
+
2294
+ public void print() {
2575
2295
  int n = 0;
2576
2296
  LmtNode lmt = top_node;
2577
- while( lmt != null )
2578
- {
2579
- System.out.println("lmt("+n+")");
2580
- for( EdgeNode edge = lmt.first_bound; (edge != null); edge = edge.next_bound )
2581
- {
2582
- System.out.println("edge.vertex_x="+edge.vertex_x+" edge.vertex_y="+edge.vertex_y);
2583
- }
2584
- n++;
2585
- lmt = lmt.next;
2297
+ while (lmt != null) {
2298
+ System.out.println("lmt(" + n + ")");
2299
+ for (EdgeNode edge = lmt.first_bound; (edge != null); edge = edge.next_bound) {
2300
+ System.out.println("edge.vertex_x=" + edge.vertex_x + " edge.vertex_y=" + edge.vertex_y);
2586
2301
  }
2302
+ n++;
2303
+ lmt = lmt.next;
2304
+ }
2587
2305
  }
2588
2306
  }
2589
-
2307
+
2590
2308
  /**
2591
- * Scanbeam tree
2309
+ * Scanbeam tree
2592
2310
  */
2593
- private static class ScanBeamTree
2594
- {
2595
- float y; /* Scanbeam node y value */
2596
- ScanBeamTree less; /* Pointer to nodes with lower y */
2597
- ScanBeamTree more; /* Pointer to nodes with higher y */
2598
-
2599
- public ScanBeamTree( float yvalue )
2600
- {
2311
+ private static class ScanBeamTree {
2312
+
2313
+ float y;
2314
+ /* Scanbeam node y value */
2315
+ ScanBeamTree less;
2316
+ /* Pointer to nodes with lower y */
2317
+ ScanBeamTree more;
2318
+
2319
+ /* Pointer to nodes with higher y */
2320
+ public ScanBeamTree(float yvalue) {
2601
2321
  y = yvalue;
2602
2322
  }
2603
2323
  }
2604
-
2324
+
2605
2325
  /**
2606
2326
  *
2607
2327
  */
2608
- private static class ScanBeamTreeEntries
2609
- {
2328
+ private static class ScanBeamTreeEntries {
2329
+
2610
2330
  int sbt_entries;
2611
2331
  ScanBeamTree sb_tree;
2612
-
2613
- public float[] build_sbt()
2614
- {
2332
+
2333
+ public float[] build_sbt() {
2615
2334
  float[] sbt = new float[sbt_entries];
2616
-
2335
+
2617
2336
  int entries = 0;
2618
- entries = inner_build_sbt( entries, sbt, sb_tree );
2619
- if( entries != sbt_entries )
2620
- {
2621
- throw new IllegalStateException("Something went wrong buildign sbt from tree.");
2622
- }
2337
+ entries = inner_build_sbt(entries, sbt, sb_tree);
2338
+ if (entries != sbt_entries) {
2339
+ throw new IllegalStateException("Something went wrong buildign sbt from tree.");
2340
+ }
2623
2341
  return sbt;
2624
2342
  }
2625
-
2626
- private int inner_build_sbt( int entries, float[] sbt, ScanBeamTree sbt_node )
2627
- {
2628
- if( sbt_node.less != null )
2629
- {
2630
- entries = inner_build_sbt(entries, sbt, sbt_node.less);
2631
- }
2632
- sbt[entries]= sbt_node.y;
2343
+
2344
+ private int inner_build_sbt(int entries, float[] sbt, ScanBeamTree sbt_node) {
2345
+ if (sbt_node.less != null) {
2346
+ entries = inner_build_sbt(entries, sbt, sbt_node.less);
2347
+ }
2348
+ sbt[entries] = sbt_node.y;
2633
2349
  entries++;
2634
- if( sbt_node.more != null )
2635
- {
2636
- entries = inner_build_sbt(entries, sbt, sbt_node.more );
2637
- }
2350
+ if (sbt_node.more != null) {
2351
+ entries = inner_build_sbt(entries, sbt, sbt_node.more);
2352
+ }
2638
2353
  return entries;
2639
2354
  }
2640
2355
  }
2641
-
2356
+
2642
2357
  /**
2643
2358
  * Intersection table
2644
2359
  */
2645
- private static class ItNode
2646
- {
2647
- EdgeNode ie0, ie1; /* Intersecting edge (bundle) pair */
2648
- float point_x, point_y; /* Point of intersection */
2649
- ItNode next; /* The next intersection table node */
2650
-
2651
- public ItNode( EdgeNode edge0, EdgeNode edge1, float x, float y, ItNode next )
2652
- {
2360
+ private static class ItNode {
2361
+
2362
+ EdgeNode ie0, ie1;
2363
+ /* Intersecting edge (bundle) pair */
2364
+ float point_x, point_y;
2365
+ /* Point of intersection */
2366
+ ItNode next;
2367
+
2368
+ /* The next intersection table node */
2369
+ public ItNode(EdgeNode edge0, EdgeNode edge1, float x, float y, ItNode next) {
2653
2370
  this.ie0 = edge0;
2654
2371
  this.ie1 = edge1;
2655
2372
  this.point_x = x;
@@ -2657,59 +2374,58 @@ class FastRClip
2657
2374
  this.next = next;
2658
2375
  }
2659
2376
  }
2660
-
2661
- private static class ItNodeTable
2662
- {
2377
+
2378
+ private static class ItNodeTable {
2379
+
2663
2380
  ItNode top_node;
2664
-
2665
- public void build_intersection_table(AetTree aet, float dy)
2666
- {
2381
+
2382
+ public void build_intersection_table(AetTree aet, float dy) {
2667
2383
  StNode st = null;
2668
-
2384
+
2669
2385
  /* Process each AET edge */
2670
- for (EdgeNode edge = aet.top_node; (edge != null); edge = edge.next)
2671
- {
2672
- if( (edge.bstate_above == BundleState.BUNDLE_HEAD) ||
2673
- (edge.bundle_above[CLIP] != 0) ||
2674
- (edge.bundle_above[SUBJ] != 0) )
2675
- {
2676
- st = add_st_edge(st, this, edge, dy);
2677
- }
2386
+ for (EdgeNode edge = aet.top_node; (edge != null); edge = edge.next) {
2387
+ if ((edge.bstate_above == BundleState.BUNDLE_HEAD)
2388
+ || (edge.bundle_above[CLIP] != 0)
2389
+ || (edge.bundle_above[SUBJ] != 0)) {
2390
+ st = add_st_edge(st, this, edge, dy);
2678
2391
  }
2392
+ }
2679
2393
  }
2680
2394
  }
2681
-
2395
+
2682
2396
  /**
2683
2397
  * Sorted edge table
2684
2398
  */
2685
- private static class StNode
2686
- {
2687
- EdgeNode edge; /* Pointer to AET edge */
2688
- float xb; /* Scanbeam bottom x coordinate */
2689
- float xt; /* Scanbeam top x coordinate */
2690
- float dx; /* Change in x for a unit y increase */
2691
- StNode prev; /* Previous edge in sorted list */
2692
-
2693
- public StNode( EdgeNode edge, StNode prev )
2694
- {
2399
+ private static class StNode {
2400
+
2401
+ EdgeNode edge;
2402
+ /* Pointer to AET edge */
2403
+ float xb;
2404
+ /* Scanbeam bottom x coordinate */
2405
+ float xt;
2406
+ /* Scanbeam top x coordinate */
2407
+ float dx;
2408
+ /* Change in x for a unit y increase */
2409
+ StNode prev;
2410
+
2411
+ /* Previous edge in sorted list */
2412
+ public StNode(EdgeNode edge, StNode prev) {
2695
2413
  this.edge = edge;
2696
2414
  this.xb = edge.xb;
2697
2415
  this.xt = edge.xt;
2698
2416
  this.dx = edge.dx;
2699
2417
  this.prev = prev;
2700
- }
2418
+ }
2701
2419
  }
2702
-
2420
+
2703
2421
  // -------------
2704
2422
  // --- DEBUG ---
2705
2423
  // -------------
2706
- static void print_sbt( float[] sbt )
2707
- {
2424
+ static void print_sbt(float[] sbt) {
2708
2425
  System.out.println("");
2709
- System.out.println("sbt.length="+sbt.length);
2710
- for( int i = 0; i < sbt.length; i++ )
2711
- {
2712
- System.out.println("sbt["+i+"]="+sbt[i]);
2713
- }
2426
+ System.out.println("sbt.length=" + sbt.length);
2427
+ for (int i = 0; i < sbt.length; i++) {
2428
+ System.out.println("sbt[" + i + "]=" + sbt[i]);
2429
+ }
2714
2430
  }
2715
2431
  }