@@ -30,6 +30,8 @@ class ObjectExtractorStreamEngine extends PDFGraphicsStreamEngine {
3030 private int clipWindingRule = -1 ;
3131 private GeneralPath currentPath = new GeneralPath ();
3232
33+ private static final float RULING_MINIMUM_LENGTH = 0.01f ;
34+
3335 protected ObjectExtractorStreamEngine (PDPage page ) {
3436 super (page );
3537 logger = LoggerFactory .getLogger (ObjectExtractorStreamEngine .class );
@@ -138,73 +140,53 @@ private void strokeOrFillPath(boolean isFill) {
138140
139141 // TODO: how to implement color filter?
140142
141- // skip the first path operation and save it as the starting position
142- float [] first = new float [ 6 ] ;
143- PathIterator pathIterator = currentPath . getPathIterator ( this . getPageTransform ());
144- float [] c = new float [6 ];
143+ // Skip the first path operation and save it as the starting point.
144+ PathIterator pathIterator = currentPath . getPathIterator ( getPageTransform ()) ;
145+
146+ float [] coordinates = new float [6 ];
145147 int currentSegment ;
146- pathIterator .currentSegment (first );
147- // last move
148- Point2D .Float start_pos = new Point2D .Float (Utils .round (first [0 ], 2 ), Utils .round (first [1 ], 2 ));
149- Point2D .Float last_move = start_pos ;
150- Point2D .Float end_pos = null ;
148+
149+ Point2D .Float startPoint = getStartPoint (pathIterator );
150+ Point2D .Float last_move = startPoint ;
151+ Point2D .Float endPoint = null ;
151152 Line2D .Float line ;
152- PointComparator pc = new PointComparator ();
153+ PointComparator pointComparator = new PointComparator ();
154+
153155 while (!pathIterator .isDone ()) {
154156 pathIterator .next ();
155- // This can be the last segment, when pi.isDone, but we need to
156- // process it
157- // otherwise us-017.pdf fails the last value.
157+ // This can be the last segment, when pathIterator.isDone, but we need to
158+ // process it otherwise us-017.pdf fails the last value.
158159 try {
159- currentSegment = pathIterator .currentSegment (c );
160+ currentSegment = pathIterator .currentSegment (coordinates );
160161 } catch (IndexOutOfBoundsException ex ) {
161162 continue ;
162163 }
163164 switch (currentSegment ) {
164165 case SEG_LINETO :
165- end_pos = new Point2D .Float (c [0 ], c [1 ]);
166-
167- if (start_pos == null || end_pos == null ) {
166+ endPoint = new Point2D .Float (coordinates [0 ], coordinates [1 ]);
167+ if (startPoint == null || endPoint == null ) {
168168 break ;
169169 }
170-
171- line = pc .compare (start_pos , end_pos ) == -1 ? new Line2D .Float (start_pos , end_pos )
172- : new Line2D .Float (end_pos , start_pos );
173-
174- if (line .intersects (this .currentClippingPath ())) {
175- Ruling r = new Ruling (line .getP1 (), line .getP2 ()).intersect (this .currentClippingPath ());
176-
177- if (r .length () > 0.01 ) {
178- this .rulings .add (r );
179- }
180- }
170+ line = getLineBetween (startPoint , endPoint , pointComparator );
171+ verifyLineIntersectsClipping (line );
181172 break ;
182173 case SEG_MOVETO :
183- last_move = new Point2D .Float (c [0 ], c [1 ]);
184- end_pos = last_move ;
174+ last_move = new Point2D .Float (coordinates [0 ], coordinates [1 ]);
175+ endPoint = last_move ;
185176 break ;
186177 case SEG_CLOSE :
187- // according to PathIterator docs:
188- // "the preceding subpath should be closed by appending a line
189- // segment
190- // back to the point corresponding to the most recent
178+ // According to PathIterator docs:
179+ // "The preceding sub-path should be closed by appending a line
180+ // segment back to the point corresponding to the most recent
191181 // SEG_MOVETO."
192- if (start_pos == null || end_pos == null ) {
182+ if (startPoint == null || endPoint == null ) {
193183 break ;
194184 }
195- line = pc .compare (end_pos , last_move ) == -1 ? new Line2D .Float (end_pos , last_move )
196- : new Line2D .Float (last_move , end_pos );
197-
198- if (line .intersects (this .currentClippingPath ())) {
199- Ruling r = new Ruling (line .getP1 (), line .getP2 ()).intersect (this .currentClippingPath ());
200-
201- if (r .length () > 0.01 ) {
202- this .rulings .add (r );
203- }
204- }
185+ line = getLineBetween (endPoint , last_move , pointComparator );
186+ verifyLineIntersectsClipping (line );
205187 break ;
206188 }
207- start_pos = end_pos ;
189+ startPoint = endPoint ;
208190 }
209191 currentPath .reset ();
210192 }
@@ -229,6 +211,31 @@ private boolean filterPathBySegmentType() {
229211 return false ;
230212 }
231213
214+ private Point2D .Float getStartPoint (PathIterator pathIterator ) {
215+ float [] startPointCoordinates = new float [6 ];
216+ pathIterator .currentSegment (startPointCoordinates );
217+ float x = Utils .round (startPointCoordinates [0 ], 2 );
218+ float y = Utils .round (startPointCoordinates [1 ], 2 );
219+ return new Point2D .Float (x , y );
220+ }
221+
222+ private Line2D .Float getLineBetween (Point2D .Float pointA , Point2D .Float pointB , PointComparator pointComparator ) {
223+ if (pointComparator .compare (pointA , pointB ) == -1 ) {
224+ return new Line2D .Float (pointA , pointB );
225+ }
226+ return new Line2D .Float (pointB , pointA );
227+ }
228+
229+ private void verifyLineIntersectsClipping (Line2D .Float line ) {
230+ Rectangle2D currentClippingPath = currentClippingPath ();
231+ if (line .intersects (currentClippingPath )) {
232+ Ruling ruling = new Ruling (line .getP1 (), line .getP2 ()).intersect (currentClippingPath );
233+ if (ruling .length () > RULING_MINIMUM_LENGTH ) {
234+ rulings .add (ruling );
235+ }
236+ }
237+ }
238+
232239 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
233240 public AffineTransform getPageTransform () {
234241 return pageTransform ;
0 commit comments