1 | /* | |
2 | Copyright 2014 by Tizra Inc. | |
3 | The contents of this file are subject to the Mozilla Public License Version 1.1 | |
4 | (the "License"); you may not use this file except in compliance with the License. | |
5 | You may obtain a copy of the License at http://www.mozilla.org/MPL/ | |
6 | ||
7 | Software distributed under the License is distributed on an "AS IS" basis, | |
8 | WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | |
9 | for the specific language governing rights and limitations under the License. | |
10 | ||
11 | The Original Code is 'iText, a free JAVA-PDF library'. | |
12 | ||
13 | The Initial Developer of the Original Code is Bruno Lowagie. Portions created by | |
14 | the Initial Developer are Copyright (C) 1999-2008 by Bruno Lowagie. | |
15 | All Rights Reserved. | |
16 | Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer | |
17 | are Copyright (C) 2000-2008 by Paulo Soares. All Rights Reserved. | |
18 | ||
19 | Contributor(s): all the names of the contributors are added in the source code | |
20 | where applicable. | |
21 | ||
22 | Alternatively, the contents of this file may be used under the terms of the | |
23 | LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the | |
24 | provisions of LGPL are applicable instead of those above. If you wish to | |
25 | allow use of your version of this file only under the terms of the LGPL | |
26 | License and not to allow others to use your version of this file under | |
27 | the MPL, indicate your decision by deleting the provisions above and | |
28 | replace them with the notice and other provisions required by the LGPL. | |
29 | If you do not delete the provisions above, a recipient may use your version | |
30 | of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. | |
31 | ||
32 | This library is free software; you can redistribute it and/or modify it | |
33 | under the terms of the MPL as stated above or under the terms of the GNU | |
34 | Library General Public License as published by the Free Software Foundation; | |
35 | either version 2 of the License, or any later version. | |
36 | ||
37 | This library is distributed in the hope that it will be useful, but WITHOUT | |
38 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
39 | FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more | |
40 | details. | |
41 | */ | |
42 | package com.lowagie.text.pdf.parser; | |
43 | ||
44 | import com.lowagie.text.ExceptionConverter; | |
45 | import com.lowagie.text.error_messages.MessageLocalization; | |
46 | import com.lowagie.text.pdf.*; | |
47 | ||
48 | import javax.annotation.Nonnull; | |
49 | import javax.annotation.Nullable; | |
50 | import java.io.ByteArrayOutputStream; | |
51 | import java.io.IOException; | |
52 | import java.util.*; | |
53 | ||
54 | /** | |
55 | * @author dgd | |
56 | */ | |
57 | @SuppressWarnings({"WeakerAccess", "unused"}) | |
58 | public class PdfContentStreamHandler { | |
59 | /** | |
60 | * A map with all supported operators operators (PDF syntax). | |
61 | */ | |
62 | private Map<String, ContentOperator> operators; | |
63 | /** | |
64 | * Stack keeping track of the graphics state. | |
65 | */ | |
66 | private Stack<GraphicsState> gsStack; | |
67 | /** | |
68 | * Text matrix. | |
69 | */ | |
70 | private Matrix textMatrix; | |
71 | /** | |
72 | * Text line matrix. | |
73 | */ | |
74 | private Matrix textLineMatrix; | |
75 | private Stack<List<TextAssemblyBuffer>> textFragmentStreams = new Stack<>(); | |
76 | private Stack<String> contextNames = new Stack<>(); | |
77 | private List<TextAssemblyBuffer> textFragments = new ArrayList<>(); | |
78 | /** | |
79 | * detail parser for text within a marked section. used by TextAssembler | |
80 | */ | |
81 | private TextAssembler renderListener; | |
82 | ||
83 | ||
84 | public PdfContentStreamHandler(TextAssembler renderListener) { | |
85 | this.renderListener = renderListener; | |
86 |
1
1. |
installDefaultOperators(); |
87 |
1
1. |
reset(); |
88 | } | |
89 | ||
90 | @Nonnull | |
91 | private static Matrix getMatrix(List<PdfObject> operands) { | |
92 | float a = ((PdfNumber) operands.get(0)).floatValue(); | |
93 | float b = ((PdfNumber) operands.get(1)).floatValue(); | |
94 | float c = ((PdfNumber) operands.get(2)).floatValue(); | |
95 | float d = ((PdfNumber) operands.get(3)).floatValue(); | |
96 | float e = ((PdfNumber) operands.get(4)).floatValue(); | |
97 | float f = ((PdfNumber) operands.get(5)).floatValue(); | |
98 |
1
1. getMatrix : mutated return of Object value for com/lowagie/text/pdf/parser/PdfContentStreamHandler::getMatrix to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return new Matrix(a, b, c, d, e, f); |
99 | } | |
100 | ||
101 | /** | |
102 | * Registers a content operator that will be called when the specified | |
103 | * operator string is encountered during content processing. Each operator | |
104 | * may be registered only once (it is not legal to have multiple operators | |
105 | * with the same operatorString) | |
106 | * | |
107 | * @param operator the operator that will receive notification when the operator | |
108 | * is encountered | |
109 | * @since 2.1.7 | |
110 | */ | |
111 | public void registerContentOperator(ContentOperator operator) { | |
112 | String operatorString = operator.getOperatorName(); | |
113 |
1
1. registerContentOperator : negated conditional → NO_COVERAGE |
if (operators.containsKey(operatorString)) { |
114 | throw new IllegalArgumentException(MessageLocalization.getComposedMessage( | |
115 | "operator.1.already.registered", operatorString)); | |
116 | } | |
117 | operators.put(operatorString, operator); | |
118 | } | |
119 | ||
120 | /** | |
121 | * Loads all the supported graphics and text state operators in a map. | |
122 | */ | |
123 | protected void installDefaultOperators() { | |
124 | operators = new HashMap<>(); | |
125 | ||
126 |
1
1. installDefaultOperators : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::registerContentOperator → NO_COVERAGE |
registerContentOperator(new PdfContentStreamHandler.PushGraphicsState()); |
127 |
1
1. installDefaultOperators : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::registerContentOperator → NO_COVERAGE |
registerContentOperator(new PdfContentStreamHandler.PopGraphicsState()); |
128 |
1
1. installDefaultOperators : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::registerContentOperator → NO_COVERAGE |
registerContentOperator(new PdfContentStreamHandler.ModifyCurrentTransformationMatrix()); |
129 |
1
1. installDefaultOperators : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::registerContentOperator → NO_COVERAGE |
registerContentOperator(new PdfContentStreamHandler.ProcessGraphicsStateResource()); |
130 | ||
131 | PdfContentStreamHandler.SetTextCharacterSpacing tcOperator = new PdfContentStreamHandler.SetTextCharacterSpacing(); | |
132 |
1
1. installDefaultOperators : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::registerContentOperator → NO_COVERAGE |
registerContentOperator(tcOperator); |
133 | PdfContentStreamHandler.SetTextWordSpacing twOperator = new PdfContentStreamHandler.SetTextWordSpacing(); | |
134 |
1
1. installDefaultOperators : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::registerContentOperator → NO_COVERAGE |
registerContentOperator(twOperator); |
135 |
1
1. installDefaultOperators : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::registerContentOperator → NO_COVERAGE |
registerContentOperator(new PdfContentStreamHandler.SetTextHorizontalScaling()); |
136 | PdfContentStreamHandler.SetTextLeading tlOperator = new PdfContentStreamHandler.SetTextLeading(); | |
137 |
1
1. installDefaultOperators : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::registerContentOperator → NO_COVERAGE |
registerContentOperator(tlOperator); |
138 |
1
1. installDefaultOperators : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::registerContentOperator → NO_COVERAGE |
registerContentOperator(new PdfContentStreamHandler.SetTextFont()); |
139 |
1
1. installDefaultOperators : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::registerContentOperator → NO_COVERAGE |
registerContentOperator(new PdfContentStreamHandler.SetTextRenderMode()); |
140 |
1
1. installDefaultOperators : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::registerContentOperator → NO_COVERAGE |
registerContentOperator(new PdfContentStreamHandler.SetTextRise()); |
141 | ||
142 |
1
1. installDefaultOperators : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::registerContentOperator → NO_COVERAGE |
registerContentOperator(new PdfContentStreamHandler.BeginText()); |
143 |
1
1. installDefaultOperators : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::registerContentOperator → NO_COVERAGE |
registerContentOperator(new PdfContentStreamHandler.EndText()); |
144 | ||
145 | PdfContentStreamHandler.TextMoveStartNextLine tdOperator = new PdfContentStreamHandler.TextMoveStartNextLine(); | |
146 |
1
1. installDefaultOperators : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::registerContentOperator → NO_COVERAGE |
registerContentOperator(tdOperator); |
147 |
1
1. installDefaultOperators : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::registerContentOperator → NO_COVERAGE |
registerContentOperator(new PdfContentStreamHandler.TextMoveStartNextLineWithLeading(tdOperator, tlOperator)); |
148 |
1
1. installDefaultOperators : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::registerContentOperator → NO_COVERAGE |
registerContentOperator(new PdfContentStreamHandler.TextSetTextMatrix()); |
149 | PdfContentStreamHandler.TextMoveNextLine tstarOperator = | |
150 | new PdfContentStreamHandler.TextMoveNextLine(tdOperator); | |
151 |
1
1. installDefaultOperators : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::registerContentOperator → NO_COVERAGE |
registerContentOperator(tstarOperator); |
152 | ||
153 | PdfContentStreamHandler.ShowText tjOperator = new PdfContentStreamHandler.ShowText(); | |
154 |
1
1. installDefaultOperators : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::registerContentOperator → NO_COVERAGE |
registerContentOperator(new PdfContentStreamHandler.ShowText()); |
155 | PdfContentStreamHandler.MoveNextLineAndShowText tickOperator = | |
156 | new PdfContentStreamHandler.MoveNextLineAndShowText(tstarOperator, tjOperator); | |
157 |
1
1. installDefaultOperators : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::registerContentOperator → NO_COVERAGE |
registerContentOperator(tickOperator); |
158 |
1
1. installDefaultOperators : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::registerContentOperator → NO_COVERAGE |
registerContentOperator( |
159 | new PdfContentStreamHandler.MoveNextLineAndShowTextWithSpacing(twOperator, tcOperator, tickOperator)); | |
160 |
1
1. installDefaultOperators : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::registerContentOperator → NO_COVERAGE |
registerContentOperator(new PdfContentStreamHandler.ShowTextArray()); |
161 | // marked sections | |
162 |
1
1. installDefaultOperators : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::registerContentOperator → NO_COVERAGE |
registerContentOperator(new BeginMarked()); |
163 |
1
1. installDefaultOperators : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::registerContentOperator → NO_COVERAGE |
registerContentOperator(new BeginMarkedDict()); |
164 |
1
1. installDefaultOperators : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::registerContentOperator → NO_COVERAGE |
registerContentOperator(new EndMarked()); |
165 | ||
166 |
1
1. installDefaultOperators : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::registerContentOperator → NO_COVERAGE |
registerContentOperator(new Do()); |
167 | } | |
168 | ||
169 | /** | |
170 | * Get the operator to process a command with a given name | |
171 | * | |
172 | * @param operatorName name of the operator that we might need to call | |
173 | * @return the operator or null if none present | |
174 | */ | |
175 | @Nonnull | |
176 | public Optional<ContentOperator> lookupOperator(String operatorName) { | |
177 |
1
1. lookupOperator : mutated return of Object value for com/lowagie/text/pdf/parser/PdfContentStreamHandler::lookupOperator to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return Optional.ofNullable(operators.get(operatorName)); |
178 | } | |
179 | ||
180 | /** | |
181 | * Invokes an operator. | |
182 | * | |
183 | * @param operator the PDF Syntax of the operator | |
184 | * @param operands a list with operands | |
185 | * @param resources Pdf Resources found in the file containing the stream. | |
186 | */ | |
187 | public void invokeOperator(PdfLiteral operator, List<PdfObject> operands, PdfDictionary resources) { | |
188 | String operatorName = operator.toString(); | |
189 | lookupOperator(operatorName) | |
190 |
1
1. invokeOperator : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
.ifPresent(contentOperator -> contentOperator.invoke(operands, this, resources)); |
191 | } | |
192 | ||
193 | void popContext() { | |
194 | String contextName = contextNames.pop(); | |
195 | List<TextAssemblyBuffer> newBuffer = textFragmentStreams.pop(); | |
196 | // put together set of unparsed text fragments | |
197 |
1
1. popContext : removed call to com/lowagie/text/pdf/parser/TextAssembler::reset → NO_COVERAGE |
renderListener.reset(); |
198 | for (TextAssemblyBuffer fragment : textFragments) { | |
199 |
1
1. popContext : removed call to com/lowagie/text/pdf/parser/TextAssemblyBuffer::accumulate → NO_COVERAGE |
fragment.accumulate(renderListener, contextName); |
200 | } | |
201 | FinalText contextResult = renderListener.endParsingContext(contextName); | |
202 | Optional.ofNullable(contextResult) | |
203 | .map(FinalText::getText) | |
204 | .filter(text -> !text.isEmpty()) | |
205 |
1
1. popContext : removed call to java/util/Optional::ifPresent → NO_COVERAGE |
.ifPresent(text -> newBuffer.add(contextResult)); |
206 | ||
207 | textFragments = newBuffer; | |
208 | } | |
209 | ||
210 | void pushContext(@Nullable String newContextName) { | |
211 | contextNames.push(newContextName); | |
212 | textFragmentStreams.push(textFragments); | |
213 | textFragments = new ArrayList<>(); | |
214 | } | |
215 | ||
216 | /** | |
217 | * Returns the current graphics state. | |
218 | * | |
219 | * @return the graphics state | |
220 | */ | |
221 | @Nonnull | |
222 | GraphicsState graphicsState() { | |
223 |
1
1. graphicsState : mutated return of Object value for com/lowagie/text/pdf/parser/PdfContentStreamHandler::graphicsState to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return gsStack.peek(); |
224 | } | |
225 | ||
226 | public void reset() { | |
227 |
2
1. reset : negated conditional → NO_COVERAGE 2. reset : negated conditional → NO_COVERAGE |
if (gsStack == null || gsStack.isEmpty()) { |
228 | gsStack = new Stack<>(); | |
229 | } | |
230 | gsStack.add(new GraphicsState()); | |
231 | textMatrix = null; | |
232 | textLineMatrix = null; | |
233 | } | |
234 | ||
235 | /** | |
236 | * Returns the current text matrix. | |
237 | * | |
238 | * @return the text matrix | |
239 | * @since 2.1.5 | |
240 | */ | |
241 | protected Matrix getCurrentTextMatrix() { | |
242 | return textMatrix; | |
243 | } | |
244 | ||
245 | /** | |
246 | * Returns the current line matrix. | |
247 | * | |
248 | * @return the line matrix | |
249 | * @since 2.1.5 | |
250 | */ | |
251 | protected Matrix getCurrentTextLineMatrix() { | |
252 | return textLineMatrix; | |
253 | } | |
254 | ||
255 | /** | |
256 | * Adjusts the text matrix for the specified adjustment value (see TJ | |
257 | * operator in the PDF spec for information) | |
258 | * | |
259 | * @param tj the text adjustment | |
260 | */ | |
261 | void applyTextAdjust(float tj) { | |
262 |
4
1. applyTextAdjust : removed negation → NO_COVERAGE 2. applyTextAdjust : Replaced float division with multiplication → NO_COVERAGE 3. applyTextAdjust : Replaced float multiplication with division → NO_COVERAGE 4. applyTextAdjust : Replaced float multiplication with division → NO_COVERAGE |
float adjustBy = -tj / 1000f * graphicsState().getFontSize() * graphicsState().getHorizontalScaling(); |
263 | textMatrix = new Matrix(adjustBy, 0).multiply(textMatrix); | |
264 | } | |
265 | ||
266 | /** | |
267 | * @return current font in processing state | |
268 | */ | |
269 | public CMapAwareDocumentFont getCurrentFont() { | |
270 |
1
1. getCurrentFont : mutated return of Object value for com/lowagie/text/pdf/parser/PdfContentStreamHandler::getCurrentFont to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return graphicsState().getFont(); |
271 | } | |
272 | ||
273 | /** | |
274 | * Displays text. | |
275 | * | |
276 | * @param string the text to display | |
277 | */ | |
278 | void displayPdfString(PdfString string) { | |
279 | ParsedText renderInfo = new ParsedText(string, graphicsState(), textMatrix); | |
280 |
1
1. displayPdfString : negated conditional → NO_COVERAGE |
if (contextNames.peek() != null) { |
281 | textFragments.add(renderInfo); | |
282 | } | |
283 | textMatrix = new Matrix(renderInfo.getUnscaledTextWidth(graphicsState()), 0) | |
284 | .multiply(textMatrix); | |
285 | } | |
286 | ||
287 | /** | |
288 | * @return result text | |
289 | */ | |
290 | @Nonnull | |
291 | public String getResultantText() { | |
292 |
2
1. getResultantText : changed conditional boundary → NO_COVERAGE 2. getResultantText : negated conditional → NO_COVERAGE |
if (contextNames.size() > 0) { |
293 | throw new RuntimeException("can't get text with unprocessed stack items"); | |
294 | } | |
295 | StringBuilder res = new StringBuilder(); | |
296 | for (TextAssemblyBuffer fragment : textFragments) { | |
297 | res.append(fragment.getText()); | |
298 | } | |
299 |
1
1. getResultantText : mutated return of Object value for com/lowagie/text/pdf/parser/PdfContentStreamHandler::getResultantText to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return res.toString(); |
300 | } | |
301 | ||
302 | /** | |
303 | * A content operator implementation (TJ). | |
304 | */ | |
305 | static class ShowTextArray implements ContentOperator { | |
306 | /** | |
307 | * @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName() | |
308 | */ | |
309 | @Nonnull | |
310 | @Override | |
311 | public String getOperatorName() { | |
312 | return "TJ"; | |
313 | } | |
314 | ||
315 | @Override | |
316 | public void invoke(List<PdfObject> operands, PdfContentStreamHandler handler, PdfDictionary resources) { | |
317 | PdfArray array = (PdfArray) operands.get(0); | |
318 |
1
1. invoke : negated conditional → NO_COVERAGE |
for (Iterator<?> i = array.listIterator(); i.hasNext(); ) { |
319 | Object entryObj = i.next(); | |
320 |
1
1. invoke : negated conditional → NO_COVERAGE |
if (entryObj instanceof PdfString) { |
321 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::displayPdfString → NO_COVERAGE |
handler.displayPdfString((PdfString) entryObj); |
322 | } else { | |
323 | float tj = ((PdfNumber) entryObj).floatValue(); | |
324 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::applyTextAdjust → NO_COVERAGE |
handler.applyTextAdjust(tj); |
325 | } | |
326 | } | |
327 | ||
328 | } | |
329 | } | |
330 | ||
331 | /** | |
332 | * A content operator implementation (BT). | |
333 | */ | |
334 | static class BeginText implements ContentOperator { | |
335 | /** | |
336 | * @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName() | |
337 | */ | |
338 | @Nonnull | |
339 | @Override | |
340 | public String getOperatorName() { | |
341 | return "BT"; | |
342 | } | |
343 | ||
344 | @Override | |
345 | public void invoke(List<PdfObject> operands, PdfContentStreamHandler handler, PdfDictionary resources) { | |
346 | handler.textMatrix = new Matrix(); | |
347 | handler.textLineMatrix = handler.textMatrix; | |
348 | } | |
349 | } | |
350 | ||
351 | /** | |
352 | * A content operator implementation (ET). | |
353 | */ | |
354 | static class EndText implements ContentOperator { | |
355 | /** | |
356 | * @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName() | |
357 | */ | |
358 | @Nonnull | |
359 | @Override | |
360 | public String getOperatorName() { | |
361 | return "ET"; | |
362 | } | |
363 | ||
364 | @Override | |
365 | public void invoke(List<PdfObject> operands, PdfContentStreamHandler handler, PdfDictionary resources) { | |
366 | handler.textMatrix = null; | |
367 | handler.textLineMatrix = null; | |
368 | } | |
369 | } | |
370 | ||
371 | /** | |
372 | * A content operator implementation (cm). | |
373 | */ | |
374 | static class ModifyCurrentTransformationMatrix implements ContentOperator { | |
375 | /** | |
376 | * @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName() | |
377 | */ | |
378 | @Nonnull | |
379 | @Override | |
380 | public String getOperatorName() { | |
381 | return "cm"; | |
382 | } | |
383 | ||
384 | @Override | |
385 | public void invoke(List<PdfObject> operands, PdfContentStreamHandler handler, PdfDictionary resources) { | |
386 | Matrix matrix = getMatrix(operands); | |
387 | GraphicsState graphicsState = handler.gsStack.peek(); | |
388 | graphicsState.multiplyCtm(matrix); | |
389 | } | |
390 | } | |
391 | ||
392 | /** | |
393 | * A content operator implementation ('). | |
394 | */ | |
395 | static class MoveNextLineAndShowText implements ContentOperator { | |
396 | private final PdfContentStreamHandler.TextMoveNextLine textMoveNextLine; | |
397 | private final PdfContentStreamHandler.ShowText showText; | |
398 | ||
399 | public MoveNextLineAndShowText( | |
400 | PdfContentStreamHandler.TextMoveNextLine textMoveNextLine, | |
401 | PdfContentStreamHandler.ShowText showText) { | |
402 | this.textMoveNextLine = textMoveNextLine; | |
403 | this.showText = showText; | |
404 | } | |
405 | ||
406 | /** | |
407 | * @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName() | |
408 | */ | |
409 | @Nonnull | |
410 | @Override | |
411 | public String getOperatorName() { | |
412 | return "'"; | |
413 | } | |
414 | ||
415 | @Override | |
416 | public void invoke(List<PdfObject> operands, PdfContentStreamHandler handler, PdfDictionary resources) { | |
417 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler$TextMoveNextLine::invoke → NO_COVERAGE |
textMoveNextLine.invoke(new ArrayList<>(0), handler, resources); |
418 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler$ShowText::invoke → NO_COVERAGE |
showText.invoke(operands, handler, resources); |
419 | } | |
420 | } | |
421 | ||
422 | /** | |
423 | * A content operator implementation ("). | |
424 | */ | |
425 | static class MoveNextLineAndShowTextWithSpacing implements ContentOperator { | |
426 | private final PdfContentStreamHandler.SetTextWordSpacing setTextWordSpacing; | |
427 | private final PdfContentStreamHandler.SetTextCharacterSpacing setTextCharacterSpacing; | |
428 | private final MoveNextLineAndShowText moveNextLineAndShowText; | |
429 | ||
430 | public MoveNextLineAndShowTextWithSpacing( | |
431 | PdfContentStreamHandler.SetTextWordSpacing setTextWordSpacing, | |
432 | PdfContentStreamHandler.SetTextCharacterSpacing setTextCharacterSpacing, | |
433 | MoveNextLineAndShowText moveNextLineAndShowText) { | |
434 | this.setTextWordSpacing = setTextWordSpacing; | |
435 | this.setTextCharacterSpacing = setTextCharacterSpacing; | |
436 | this.moveNextLineAndShowText = moveNextLineAndShowText; | |
437 | } | |
438 | ||
439 | /** | |
440 | * @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName() | |
441 | */ | |
442 | @Nonnull | |
443 | @Override | |
444 | public String getOperatorName() { | |
445 | return "\""; | |
446 | } | |
447 | ||
448 | @Override | |
449 | public void invoke(List<PdfObject> operands, PdfContentStreamHandler handler, PdfDictionary resources) { | |
450 | PdfNumber aw = (PdfNumber) operands.get(0); | |
451 | PdfNumber ac = (PdfNumber) operands.get(1); | |
452 | PdfString string = (PdfString) operands.get(2); | |
453 | ||
454 | List<PdfObject> twOperands = new ArrayList<>(1); | |
455 |
1
1. invoke : removed call to java/util/List::add → NO_COVERAGE |
twOperands.add(0, aw); |
456 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler$SetTextWordSpacing::invoke → NO_COVERAGE |
setTextWordSpacing.invoke(twOperands, handler, resources); |
457 | ||
458 | List<PdfObject> tcOperands = new ArrayList<>(1); | |
459 |
1
1. invoke : removed call to java/util/List::add → NO_COVERAGE |
tcOperands.add(0, ac); |
460 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler$SetTextCharacterSpacing::invoke → NO_COVERAGE |
setTextCharacterSpacing.invoke(tcOperands, handler, resources); |
461 | ||
462 | List<PdfObject> tickOperands = new ArrayList<>(1); | |
463 |
1
1. invoke : removed call to java/util/List::add → NO_COVERAGE |
tickOperands.add(0, string); |
464 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler$MoveNextLineAndShowText::invoke → NO_COVERAGE |
moveNextLineAndShowText.invoke(tickOperands, handler, resources); |
465 | } | |
466 | } | |
467 | ||
468 | /** | |
469 | * A content operator implementation (Q). | |
470 | */ | |
471 | static class PopGraphicsState implements ContentOperator { | |
472 | /** | |
473 | * @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName() | |
474 | */ | |
475 | @Nonnull | |
476 | @Override | |
477 | public String getOperatorName() { | |
478 | return "Q"; | |
479 | } | |
480 | ||
481 | @Override | |
482 | public void invoke(List<PdfObject> operands, PdfContentStreamHandler handler, PdfDictionary resources) { | |
483 | handler.gsStack.pop(); | |
484 | } | |
485 | } | |
486 | ||
487 | /** | |
488 | * A content operator implementation (gs). | |
489 | */ | |
490 | static class ProcessGraphicsStateResource implements ContentOperator { | |
491 | /** | |
492 | * @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName() | |
493 | */ | |
494 | @Nonnull | |
495 | @Override | |
496 | public String getOperatorName() { | |
497 | return "gs"; | |
498 | } | |
499 | ||
500 | @Override | |
501 | public void invoke(List<PdfObject> operands, PdfContentStreamHandler handler, PdfDictionary resources) { | |
502 | PdfName dictionaryName = (PdfName) operands.get(0); | |
503 | PdfDictionary extGState = resources.getAsDict(PdfName.EXTGSTATE); | |
504 |
1
1. invoke : negated conditional → NO_COVERAGE |
if (extGState == null) { |
505 | throw new IllegalArgumentException( | |
506 | MessageLocalization.getComposedMessage( | |
507 | "resources.do.not.contain.extgstate.entry.unable.to.process.operator.1", | |
508 | getOperatorName())); | |
509 | } | |
510 | PdfDictionary gsDic = extGState.getAsDict(dictionaryName); | |
511 |
1
1. invoke : negated conditional → NO_COVERAGE |
if (gsDic == null) { |
512 | throw new IllegalArgumentException(MessageLocalization.getComposedMessage( | |
513 | "1.is.an.unknown.graphics.state.dictionary", dictionaryName)); | |
514 | } | |
515 | ||
516 | // at this point, all we care about is the FONT entry in the GS | |
517 | // dictionary | |
518 | PdfArray fontParameter = gsDic.getAsArray(PdfName.FONT); | |
519 |
1
1. invoke : negated conditional → NO_COVERAGE |
if (fontParameter != null) { |
520 | PdfObject pdfObject = fontParameter.getPdfObject(0); | |
521 | CMapAwareDocumentFont font = new CMapAwareDocumentFont((PRIndirectReference) pdfObject); | |
522 | float size = fontParameter.getAsNumber(1).floatValue(); | |
523 | ||
524 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/GraphicsState::setFont → NO_COVERAGE |
handler.graphicsState().setFont(font); |
525 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/GraphicsState::setFontSize → NO_COVERAGE |
handler.graphicsState().setFontSize(size); |
526 | } | |
527 | } | |
528 | } | |
529 | ||
530 | /** | |
531 | * A content operator implementation (q). | |
532 | */ | |
533 | static class PushGraphicsState implements ContentOperator { | |
534 | /** | |
535 | * @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName() | |
536 | */ | |
537 | @Nonnull | |
538 | @Override | |
539 | public String getOperatorName() { | |
540 | return "q"; | |
541 | } | |
542 | ||
543 | @Override | |
544 | public void invoke(List<PdfObject> operands, PdfContentStreamHandler handler, PdfDictionary resources) { | |
545 | GraphicsState gs = handler.gsStack.peek(); | |
546 | GraphicsState copy = new GraphicsState(gs); | |
547 | handler.gsStack.push(copy); | |
548 | } | |
549 | } | |
550 | ||
551 | /** | |
552 | * A content operator implementation (Tc). | |
553 | */ | |
554 | static class SetTextCharacterSpacing implements ContentOperator { | |
555 | /** | |
556 | * @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName() | |
557 | */ | |
558 | @Nonnull | |
559 | @Override | |
560 | public String getOperatorName() { | |
561 | return "Tc"; | |
562 | } | |
563 | ||
564 | @Override | |
565 | public void invoke(List<PdfObject> operands, PdfContentStreamHandler handler, PdfDictionary resources) { | |
566 | PdfNumber charSpace = (PdfNumber) operands.get(0); | |
567 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/GraphicsState::setCharacterSpacing → NO_COVERAGE |
handler.graphicsState().setCharacterSpacing(charSpace.floatValue()); |
568 | } | |
569 | } | |
570 | ||
571 | /** | |
572 | * A content operator implementation (Tf). | |
573 | */ | |
574 | static class SetTextFont implements ContentOperator { | |
575 | /** | |
576 | * @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName() | |
577 | */ | |
578 | @Nonnull | |
579 | @Override | |
580 | public String getOperatorName() { | |
581 | return "Tf"; | |
582 | } | |
583 | ||
584 | @Override | |
585 | public void invoke(List<PdfObject> operands, PdfContentStreamHandler handler, PdfDictionary resources) { | |
586 | PdfName fontResourceName = (PdfName) operands.get(0); | |
587 | float size = ((PdfNumber) operands.get(1)).floatValue(); | |
588 | ||
589 | PdfDictionary fontsDictionary = resources.getAsDict(PdfName.FONT); | |
590 | PdfObject pdfObject = fontsDictionary.get(fontResourceName); | |
591 | CMapAwareDocumentFont font = new CMapAwareDocumentFont((PRIndirectReference) pdfObject); | |
592 | ||
593 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/GraphicsState::setFont → NO_COVERAGE |
handler.graphicsState().setFont(font); |
594 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/GraphicsState::setFontSize → NO_COVERAGE |
handler.graphicsState().setFontSize(size); |
595 | } | |
596 | } | |
597 | ||
598 | /** | |
599 | * A content operator implementation (Tm). | |
600 | */ | |
601 | static class TextSetTextMatrix implements ContentOperator { | |
602 | /** | |
603 | * @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName() | |
604 | */ | |
605 | @Nonnull | |
606 | @Override | |
607 | public String getOperatorName() { | |
608 | return "Tm"; | |
609 | } | |
610 | ||
611 | @Override | |
612 | public void invoke(List<PdfObject> operands, PdfContentStreamHandler handler, PdfDictionary resources) { | |
613 | handler.textLineMatrix = getMatrix(operands); | |
614 | handler.textMatrix = handler.textLineMatrix; | |
615 | } | |
616 | } | |
617 | ||
618 | /** | |
619 | * A content operator implementation (TD). | |
620 | */ | |
621 | static class TextMoveStartNextLineWithLeading implements ContentOperator { | |
622 | private final PdfContentStreamHandler.TextMoveStartNextLine moveStartNextLine; | |
623 | ||
624 | private final PdfContentStreamHandler.SetTextLeading setTextLeading; | |
625 | ||
626 | public TextMoveStartNextLineWithLeading( | |
627 | PdfContentStreamHandler.TextMoveStartNextLine moveStartNextLine, | |
628 | PdfContentStreamHandler.SetTextLeading setTextLeading) { | |
629 | this.moveStartNextLine = moveStartNextLine; | |
630 | this.setTextLeading = setTextLeading; | |
631 | } | |
632 | ||
633 | /** | |
634 | * @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName() | |
635 | */ | |
636 | @Nonnull | |
637 | @Override | |
638 | public String getOperatorName() { | |
639 | return "TD"; | |
640 | } | |
641 | ||
642 | @Override | |
643 | public void invoke(List<PdfObject> operands, PdfContentStreamHandler handler, PdfDictionary resources) { | |
644 | float ty = ((PdfNumber) operands.get(1)).floatValue(); | |
645 | ||
646 | List<PdfObject> tlOperands = new ArrayList<>(1); | |
647 |
2
1. invoke : removed negation → NO_COVERAGE 2. invoke : removed call to java/util/List::add → NO_COVERAGE |
tlOperands.add(0, new PdfNumber(-ty)); |
648 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler$SetTextLeading::invoke → NO_COVERAGE |
setTextLeading.invoke(tlOperands, handler, resources); |
649 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler$TextMoveStartNextLine::invoke → NO_COVERAGE |
moveStartNextLine.invoke(operands, handler, resources); |
650 | } | |
651 | } | |
652 | ||
653 | /** | |
654 | * A content operator implementation (Tj). | |
655 | */ | |
656 | static class ShowText implements ContentOperator { | |
657 | /** | |
658 | * @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName() | |
659 | */ | |
660 | @Nonnull | |
661 | @Override | |
662 | public String getOperatorName() { | |
663 | return "Tj"; | |
664 | } | |
665 | ||
666 | @Override | |
667 | public void invoke(List<PdfObject> operands, PdfContentStreamHandler handler, PdfDictionary resources) { | |
668 | PdfString string = (PdfString) operands.get(0); | |
669 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::displayPdfString → NO_COVERAGE |
handler.displayPdfString(string); |
670 | } | |
671 | } | |
672 | ||
673 | /** | |
674 | * A content operator implementation (T*). | |
675 | */ | |
676 | static class TextMoveNextLine implements ContentOperator { | |
677 | private final TextMoveStartNextLine moveStartNextLine; | |
678 | ||
679 | public TextMoveNextLine(TextMoveStartNextLine moveStartNextLine) { | |
680 | this.moveStartNextLine = moveStartNextLine; | |
681 | } | |
682 | ||
683 | /** | |
684 | * @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName() | |
685 | */ | |
686 | @Nonnull | |
687 | @Override | |
688 | public String getOperatorName() { | |
689 | return "T*"; | |
690 | } | |
691 | ||
692 | @Override | |
693 | public void invoke(List<PdfObject> operands, PdfContentStreamHandler handler, PdfDictionary resources) { | |
694 | List<PdfObject> tdoperands = new ArrayList<>(2); | |
695 |
1
1. invoke : removed call to java/util/List::add → NO_COVERAGE |
tdoperands.add(0, new PdfNumber(0)); |
696 |
2
1. invoke : removed negation → NO_COVERAGE 2. invoke : removed call to java/util/List::add → NO_COVERAGE |
tdoperands.add(1, new PdfNumber(-handler.graphicsState().getLeading())); |
697 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler$TextMoveStartNextLine::invoke → NO_COVERAGE |
moveStartNextLine.invoke(tdoperands, handler, resources); |
698 | } | |
699 | } | |
700 | ||
701 | /** | |
702 | * A content operator implementation (Td). | |
703 | */ | |
704 | static class TextMoveStartNextLine implements ContentOperator { | |
705 | /** | |
706 | * @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName() | |
707 | */ | |
708 | @Nonnull | |
709 | @Override | |
710 | public String getOperatorName() { | |
711 | return "Td"; | |
712 | } | |
713 | ||
714 | @Override | |
715 | public void invoke(List<PdfObject> operands, PdfContentStreamHandler handler, PdfDictionary resources) { | |
716 | float tx = ((PdfNumber) operands.get(0)).floatValue(); | |
717 | float ty = ((PdfNumber) operands.get(1)).floatValue(); | |
718 | ||
719 | Matrix translationMatrix = new Matrix(tx, ty); | |
720 | handler.textMatrix = translationMatrix.multiply(handler.textLineMatrix); | |
721 | handler.textLineMatrix = handler.textMatrix; | |
722 | } | |
723 | } | |
724 | ||
725 | /** | |
726 | * A content operator implementation (Tr). | |
727 | */ | |
728 | static class SetTextRenderMode implements ContentOperator { | |
729 | /** | |
730 | * @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName() | |
731 | */ | |
732 | @Nonnull | |
733 | @Override | |
734 | public String getOperatorName() { | |
735 | return "Tr"; | |
736 | } | |
737 | ||
738 | @Override | |
739 | public void invoke(List<PdfObject> operands, PdfContentStreamHandler handler, PdfDictionary resources) { | |
740 | PdfNumber render = (PdfNumber) operands.get(0); | |
741 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/GraphicsState::setRenderMode → NO_COVERAGE |
handler.graphicsState().setRenderMode(render.intValue()); |
742 | } | |
743 | } | |
744 | ||
745 | /** | |
746 | * A content operator implementation (Ts). | |
747 | */ | |
748 | static class SetTextRise implements ContentOperator { | |
749 | /** | |
750 | * @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName() | |
751 | */ | |
752 | @Nonnull | |
753 | @Override | |
754 | public String getOperatorName() { | |
755 | return "Ts"; | |
756 | } | |
757 | ||
758 | @Override | |
759 | public void invoke(List<PdfObject> operands, PdfContentStreamHandler handler, PdfDictionary resources) { | |
760 | PdfNumber rise = (PdfNumber) operands.get(0); | |
761 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/GraphicsState::setRise → NO_COVERAGE |
handler.graphicsState().setRise(rise.floatValue()); |
762 | } | |
763 | } | |
764 | ||
765 | /** | |
766 | * A content operator implementation (TL). | |
767 | */ | |
768 | static class SetTextLeading implements ContentOperator { | |
769 | /** | |
770 | * @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName() | |
771 | */ | |
772 | @Nonnull | |
773 | @Override | |
774 | public String getOperatorName() { | |
775 | return "TL"; | |
776 | } | |
777 | ||
778 | @Override | |
779 | public void invoke(List<PdfObject> operands, PdfContentStreamHandler handler, PdfDictionary resources) { | |
780 | PdfNumber leading = (PdfNumber) operands.get(0); | |
781 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/GraphicsState::setLeading → NO_COVERAGE |
handler.graphicsState().setLeading(leading.floatValue()); |
782 | } | |
783 | } | |
784 | ||
785 | /** | |
786 | * A content operator implementation (Tz). | |
787 | */ | |
788 | static class SetTextHorizontalScaling implements ContentOperator { | |
789 | /** | |
790 | * @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName() | |
791 | */ | |
792 | @Nonnull | |
793 | @Override | |
794 | public String getOperatorName() { | |
795 | return "Tz"; | |
796 | } | |
797 | ||
798 | @Override | |
799 | public void invoke(List<PdfObject> operands, PdfContentStreamHandler handler, PdfDictionary resources) { | |
800 | PdfNumber scale = (PdfNumber) operands.get(0); | |
801 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/GraphicsState::setHorizontalScaling → NO_COVERAGE |
handler.graphicsState().setHorizontalScaling(scale.floatValue()); |
802 | } | |
803 | } | |
804 | ||
805 | /** | |
806 | * A content operator implementation (Tw). | |
807 | */ | |
808 | static class SetTextWordSpacing implements ContentOperator { | |
809 | /** | |
810 | * @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName() | |
811 | */ | |
812 | @Nonnull | |
813 | @Override | |
814 | public String getOperatorName() { | |
815 | return "Tw"; | |
816 | } | |
817 | ||
818 | @Override | |
819 | public void invoke(List<PdfObject> operands, PdfContentStreamHandler handler, PdfDictionary resources) { | |
820 | PdfNumber wordSpace = (PdfNumber) operands.get(0); | |
821 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/GraphicsState::setWordSpacing → NO_COVERAGE |
handler.graphicsState().setWordSpacing(wordSpace.floatValue()); |
822 | } | |
823 | } | |
824 | ||
825 | /** | |
826 | * A content operator implementation (BMC). | |
827 | */ | |
828 | private static class BeginMarked implements ContentOperator { | |
829 | /** | |
830 | * @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName() | |
831 | */ | |
832 | @Nonnull | |
833 | @Override | |
834 | public String getOperatorName() { | |
835 | return "BMC"; | |
836 | } | |
837 | ||
838 | @Override | |
839 | public void invoke(List<PdfObject> operands, PdfContentStreamHandler handler, PdfDictionary resources) { | |
840 | PdfName tagName = (PdfName) operands.get(0); | |
841 | String realName = tagName.toString().substring(1).toLowerCase(Locale.ROOT); | |
842 |
2
1. invoke : negated conditional → NO_COVERAGE 2. invoke : negated conditional → NO_COVERAGE |
if ("artifact".equals(realName) || "placedpdf".equals(realName)) { |
843 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::pushContext → NO_COVERAGE |
handler.pushContext(null); |
844 | } else { | |
845 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::pushContext → NO_COVERAGE |
handler.pushContext(realName); |
846 | } | |
847 | } | |
848 | ||
849 | } | |
850 | ||
851 | /** | |
852 | * A content operator implementation (BDC). | |
853 | */ | |
854 | private static class BeginMarkedDict implements ContentOperator { | |
855 | /** | |
856 | * @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName() | |
857 | */ | |
858 | @Nonnull | |
859 | @Override | |
860 | public String getOperatorName() { | |
861 | return "BDC"; | |
862 | } | |
863 | ||
864 | @Override | |
865 | public void invoke(List<PdfObject> operands, PdfContentStreamHandler handler, PdfDictionary resources) { | |
866 | PdfObject firstOperand = operands.get(0); | |
867 | String tagName = firstOperand.toString().substring(1).toLowerCase(Locale.ROOT); | |
868 |
2
1. invoke : negated conditional → NO_COVERAGE 2. invoke : negated conditional → NO_COVERAGE |
if ("artifact".equals(tagName) || "placedpdf".equals(tagName) |
869 |
1
1. invoke : negated conditional → NO_COVERAGE |
|| handler.contextNames.peek() == null) { |
870 | tagName = null; | |
871 |
1
1. invoke : negated conditional → NO_COVERAGE |
} else if ("l".equals(tagName)) { |
872 | tagName = "ul"; | |
873 | } | |
874 | PdfDictionary attrs = getBDCDictionary(operands, resources); | |
875 |
2
1. invoke : negated conditional → NO_COVERAGE 2. invoke : negated conditional → NO_COVERAGE |
if (attrs != null && tagName != null) { |
876 | PdfString alternateText = attrs.getAsString(PdfName.E); | |
877 |
1
1. invoke : negated conditional → NO_COVERAGE |
if (alternateText != null) { |
878 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::pushContext → NO_COVERAGE |
handler.pushContext(tagName); |
879 | handler.textFragments | |
880 | .add(new FinalText(alternateText.toString())); | |
881 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::popContext → NO_COVERAGE |
handler.popContext(); |
882 | // ignore rest of the content of this element | |
883 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::pushContext → NO_COVERAGE |
handler.pushContext(null); |
884 | return; | |
885 |
1
1. invoke : negated conditional → NO_COVERAGE |
} else if (attrs.get(PdfName.TYPE) != null) { |
886 | // ignore tag for non-tag marked content that sometimes | |
887 | // shows up. | |
888 | tagName = ""; | |
889 | } | |
890 | } | |
891 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::pushContext → NO_COVERAGE |
handler.pushContext(tagName); |
892 | } | |
893 | ||
894 | /** | |
895 | * @param operands | |
896 | * @param resources | |
897 | * @return | |
898 | */ | |
899 | private PdfDictionary getBDCDictionary(List<PdfObject> operands, PdfDictionary resources) { | |
900 | PdfObject pdfObject = operands.get(1); | |
901 |
1
1. getBDCDictionary : negated conditional → NO_COVERAGE |
if (pdfObject.isName()) { |
902 | PdfDictionary properties = resources.getAsDict(PdfName.PROPERTIES); | |
903 | PdfIndirectReference ir = properties.getAsIndirectObject((PdfName) pdfObject); | |
904 |
1
1. getBDCDictionary : negated conditional → NO_COVERAGE |
if (ir != null) { |
905 | pdfObject = ir.getIndRef(); | |
906 | } else { | |
907 | pdfObject = properties.getAsDict((PdfName) pdfObject); | |
908 | } | |
909 | } | |
910 |
1
1. getBDCDictionary : mutated return of Object value for com/lowagie/text/pdf/parser/PdfContentStreamHandler$BeginMarkedDict::getBDCDictionary to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return (PdfDictionary) pdfObject; |
911 | } | |
912 | } | |
913 | ||
914 | /** | |
915 | * A content operator implementation (EMC). | |
916 | */ | |
917 | private static class EndMarked implements ContentOperator { | |
918 | /** | |
919 | * @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName() | |
920 | */ | |
921 | @Nonnull | |
922 | @Override | |
923 | public String getOperatorName() { | |
924 | return "EMC"; | |
925 | } | |
926 | ||
927 | @Override | |
928 | public void invoke(List<PdfObject> operands, PdfContentStreamHandler handler, PdfDictionary resources) { | |
929 | handler.popContext(); | |
930 | } | |
931 | } | |
932 | ||
933 | private class Do implements ContentOperator { | |
934 | /** | |
935 | * @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName() | |
936 | */ | |
937 | @Nonnull | |
938 | @Override | |
939 | public String getOperatorName() { | |
940 | return "Do"; | |
941 | } | |
942 | ||
943 | @Override | |
944 | public void invoke(List<PdfObject> operands, PdfContentStreamHandler handler, PdfDictionary resources) { | |
945 | PdfObject firstOperand = operands.get(0); | |
946 |
1
1. invoke : negated conditional → NO_COVERAGE |
if (firstOperand instanceof PdfName) { |
947 | PdfName name = (PdfName) firstOperand; | |
948 | PdfDictionary dictionary = resources.getAsDict(PdfName.XOBJECT); | |
949 |
1
1. invoke : negated conditional → NO_COVERAGE |
if (dictionary == null) { |
950 | return; | |
951 | } | |
952 | PdfStream stream = (PdfStream) dictionary.getDirectObject(name); | |
953 | PdfName subType = stream.getAsName(PdfName.SUBTYPE); | |
954 |
1
1. invoke : negated conditional → NO_COVERAGE |
if (PdfName.FORM.equals(subType)) { |
955 | PdfDictionary resources2 = stream.getAsDict(PdfName.RESOURCES); | |
956 | byte[] data; | |
957 | try { | |
958 | data = getContentBytesFromPdfObject(stream); | |
959 | } catch (IOException ex) { | |
960 | throw new ExceptionConverter(ex); | |
961 | } | |
962 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler$PushGraphicsState::invoke → NO_COVERAGE |
new PushGraphicsState().invoke(operands, handler, resources); |
963 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler$Do::processContent → NO_COVERAGE |
processContent(data, resources2); |
964 |
1
1. invoke : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler$PopGraphicsState::invoke → NO_COVERAGE |
new PopGraphicsState().invoke(operands, handler, resources); |
965 | } | |
966 | } | |
967 | ||
968 | } | |
969 | ||
970 | private void processContent(byte[] contentBytes, PdfDictionary resources) { | |
971 | try { | |
972 | PdfContentParser pdfContentParser = new PdfContentParser(new PRTokeniser(contentBytes)); | |
973 | List<PdfObject> operands = new ArrayList<>(); | |
974 |
1
1. processContent : negated conditional → NO_COVERAGE |
while (!pdfContentParser.parse(operands).isEmpty()) { |
975 |
1
1. processContent : Replaced integer subtraction with addition → NO_COVERAGE |
PdfLiteral operator = (PdfLiteral) operands.get(operands.size() - 1); |
976 |
1
1. processContent : removed call to com/lowagie/text/pdf/parser/PdfContentStreamHandler::invokeOperator → NO_COVERAGE |
invokeOperator(operator, operands, resources); |
977 | } | |
978 | } catch (Exception e) { | |
979 | throw new ExceptionConverter(e); | |
980 | } | |
981 | } | |
982 | ||
983 | ||
984 | private byte[] getContentBytesFromPdfObject(PdfObject object) throws IOException { | |
985 | switch (object.type()) { | |
986 | case PdfObject.INDIRECT: | |
987 |
1
1. getContentBytesFromPdfObject : mutated return of Object value for com/lowagie/text/pdf/parser/PdfContentStreamHandler$Do::getContentBytesFromPdfObject to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return getContentBytesFromPdfObject(PdfReader.getPdfObject(object)); |
988 | case PdfObject.STREAM: | |
989 |
1
1. getContentBytesFromPdfObject : mutated return of Object value for com/lowagie/text/pdf/parser/PdfContentStreamHandler$Do::getContentBytesFromPdfObject to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return PdfReader.getStreamBytes((PRStream) PdfReader.getPdfObject(object)); |
990 | case PdfObject.ARRAY: | |
991 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |
992 | ListIterator<PdfObject> iter = ((PdfArray) object).listIterator(); | |
993 |
1
1. getContentBytesFromPdfObject : negated conditional → NO_COVERAGE |
while (iter.hasNext()) { |
994 | PdfObject element = iter.next(); | |
995 |
1
1. getContentBytesFromPdfObject : removed call to java/io/ByteArrayOutputStream::write → NO_COVERAGE |
baos.write(getContentBytesFromPdfObject(element)); |
996 | } | |
997 |
1
1. getContentBytesFromPdfObject : mutated return of Object value for com/lowagie/text/pdf/parser/PdfContentStreamHandler$Do::getContentBytesFromPdfObject to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return baos.toByteArray(); |
998 | default: | |
999 | throw new IllegalStateException("Unsupported type: " + object.getClass().getCanonicalName()); | |
1000 | } | |
1001 | } | |
1002 | } | |
1003 | } | |
Mutations | ||
86 |
1.1 |
|
87 |
1.1 |
|
98 |
1.1 |
|
113 |
1.1 |
|
126 |
1.1 |
|
127 |
1.1 |
|
128 |
1.1 |
|
129 |
1.1 |
|
132 |
1.1 |
|
134 |
1.1 |
|
135 |
1.1 |
|
137 |
1.1 |
|
138 |
1.1 |
|
139 |
1.1 |
|
140 |
1.1 |
|
142 |
1.1 |
|
143 |
1.1 |
|
146 |
1.1 |
|
147 |
1.1 |
|
148 |
1.1 |
|
151 |
1.1 |
|
154 |
1.1 |
|
157 |
1.1 |
|
158 |
1.1 |
|
160 |
1.1 |
|
162 |
1.1 |
|
163 |
1.1 |
|
164 |
1.1 |
|
166 |
1.1 |
|
177 |
1.1 |
|
190 |
1.1 |
|
197 |
1.1 |
|
199 |
1.1 |
|
205 |
1.1 |
|
223 |
1.1 |
|
227 |
1.1 2.2 |
|
262 |
1.1 2.2 3.3 4.4 |
|
270 |
1.1 |
|
280 |
1.1 |
|
292 |
1.1 2.2 |
|
299 |
1.1 |
|
318 |
1.1 |
|
320 |
1.1 |
|
321 |
1.1 |
|
324 |
1.1 |
|
417 |
1.1 |
|
418 |
1.1 |
|
455 |
1.1 |
|
456 |
1.1 |
|
459 |
1.1 |
|
460 |
1.1 |
|
463 |
1.1 |
|
464 |
1.1 |
|
504 |
1.1 |
|
511 |
1.1 |
|
519 |
1.1 |
|
524 |
1.1 |
|
525 |
1.1 |
|
567 |
1.1 |
|
593 |
1.1 |
|
594 |
1.1 |
|
647 |
1.1 2.2 |
|
648 |
1.1 |
|
649 |
1.1 |
|
669 |
1.1 |
|
695 |
1.1 |
|
696 |
1.1 2.2 |
|
697 |
1.1 |
|
741 |
1.1 |
|
761 |
1.1 |
|
781 |
1.1 |
|
801 |
1.1 |
|
821 |
1.1 |
|
842 |
1.1 2.2 |
|
843 |
1.1 |
|
845 |
1.1 |
|
868 |
1.1 2.2 |
|
869 |
1.1 |
|
871 |
1.1 |
|
875 |
1.1 2.2 |
|
877 |
1.1 |
|
878 |
1.1 |
|
881 |
1.1 |
|
883 |
1.1 |
|
885 |
1.1 |
|
891 |
1.1 |
|
901 |
1.1 |
|
904 |
1.1 |
|
910 |
1.1 |
|
946 |
1.1 |
|
949 |
1.1 |
|
954 |
1.1 |
|
962 |
1.1 |
|
963 |
1.1 |
|
964 |
1.1 |
|
974 |
1.1 |
|
975 |
1.1 |
|
976 |
1.1 |
|
987 |
1.1 |
|
989 |
1.1 |
|
993 |
1.1 |
|
995 |
1.1 |
|
997 |
1.1 |