Skip to content

Commit f7e1976

Browse files
ZaqueuCavalcantejazzido
authored andcommitted
Filter path by segment type.
1 parent 8a78148 commit f7e1976

1 file changed

Lines changed: 39 additions & 33 deletions

File tree

src/main/java/technology/tabula/ObjectExtractorStreamEngine.java

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import org.slf4j.Logger;
2020
import org.slf4j.LoggerFactory;
2121

22+
import static java.awt.geom.PathIterator.*;
23+
2224
class ObjectExtractorStreamEngine extends PDFGraphicsStreamEngine {
2325

2426
protected List<Ruling> rulings;
@@ -119,64 +121,47 @@ public void moveTo(float x, float y) {
119121
@Override
120122
public void shadingFill(COSName arg0) {}
121123

124+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
122125
@Override
123126
public void strokePath() {
124127
strokeOrFillPath(false);
125128
}
126129

127130
private void strokeOrFillPath(boolean isFill) {
128-
GeneralPath path = this.currentPath;
129-
130-
if (!this.extractRulingLines) {
131-
this.currentPath.reset();
131+
if (!extractRulingLines) {
132+
currentPath.reset();
132133
return;
133134
}
134135

135-
PathIterator pi = path.getPathIterator(this.getPageTransform());
136-
float[] c = new float[6];
137-
int currentSegment;
138-
139-
// skip paths whose first operation is not a MOVETO
140-
// or contains operations other than LINETO, MOVETO or CLOSE
141-
if ((pi.currentSegment(c) != PathIterator.SEG_MOVETO)) {
142-
path.reset();
143-
return;
144-
}
145-
pi.next();
146-
while (!pi.isDone()) {
147-
currentSegment = pi.currentSegment(c);
148-
if (currentSegment != PathIterator.SEG_LINETO && currentSegment != PathIterator.SEG_CLOSE
149-
&& currentSegment != PathIterator.SEG_MOVETO) {
150-
path.reset();
151-
return;
152-
}
153-
pi.next();
154-
}
136+
boolean didNotPassedTheFilter = filterPathBySegmentType();
137+
if (didNotPassedTheFilter) return;
155138

156139
// TODO: how to implement color filter?
157140

158141
// skip the first path operation and save it as the starting position
159142
float[] first = new float[6];
160-
pi = path.getPathIterator(this.getPageTransform());
161-
pi.currentSegment(first);
143+
PathIterator pathIterator = currentPath.getPathIterator(this.getPageTransform());
144+
float[] c = new float[6];
145+
int currentSegment;
146+
pathIterator.currentSegment(first);
162147
// last move
163148
Point2D.Float start_pos = new Point2D.Float(Utils.round(first[0], 2), Utils.round(first[1], 2));
164149
Point2D.Float last_move = start_pos;
165150
Point2D.Float end_pos = null;
166151
Line2D.Float line;
167152
PointComparator pc = new PointComparator();
168-
while (!pi.isDone()) {
169-
pi.next();
153+
while (!pathIterator.isDone()) {
154+
pathIterator.next();
170155
// This can be the last segment, when pi.isDone, but we need to
171156
// process it
172157
// otherwise us-017.pdf fails the last value.
173158
try {
174-
currentSegment = pi.currentSegment(c);
159+
currentSegment = pathIterator.currentSegment(c);
175160
} catch (IndexOutOfBoundsException ex) {
176161
continue;
177162
}
178163
switch (currentSegment) {
179-
case PathIterator.SEG_LINETO:
164+
case SEG_LINETO:
180165
end_pos = new Point2D.Float(c[0], c[1]);
181166

182167
if (start_pos == null || end_pos == null) {
@@ -194,11 +179,11 @@ private void strokeOrFillPath(boolean isFill) {
194179
}
195180
}
196181
break;
197-
case PathIterator.SEG_MOVETO:
182+
case SEG_MOVETO:
198183
last_move = new Point2D.Float(c[0], c[1]);
199184
end_pos = last_move;
200185
break;
201-
case PathIterator.SEG_CLOSE:
186+
case SEG_CLOSE:
202187
// according to PathIterator docs:
203188
// "the preceding subpath should be closed by appending a line
204189
// segment
@@ -221,9 +206,30 @@ private void strokeOrFillPath(boolean isFill) {
221206
}
222207
start_pos = end_pos;
223208
}
224-
path.reset();
209+
currentPath.reset();
225210
}
226211

212+
private boolean filterPathBySegmentType() {
213+
PathIterator pathIterator = currentPath.getPathIterator(pageTransform);
214+
float[] coordinates = new float[6];
215+
int currentSegmentType = pathIterator.currentSegment(coordinates);
216+
if (currentSegmentType != SEG_MOVETO) {
217+
currentPath.reset();
218+
return true;
219+
}
220+
pathIterator.next();
221+
while (!pathIterator.isDone()) {
222+
currentSegmentType = pathIterator.currentSegment(coordinates);
223+
if (currentSegmentType != SEG_LINETO && currentSegmentType != SEG_CLOSE && currentSegmentType != SEG_MOVETO) {
224+
currentPath.reset();
225+
return true;
226+
}
227+
pathIterator.next();
228+
}
229+
return false;
230+
}
231+
232+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
227233
public AffineTransform getPageTransform() {
228234
return pageTransform;
229235
}

0 commit comments

Comments
 (0)