1 | /* | |
2 | * | |
3 | * Copyright 2002 by Paulo Soares. | |
4 | * | |
5 | * The contents of this file are subject to the Mozilla Public License Version 1.1 | |
6 | * (the "License"); you may not use this file except in compliance with the License. | |
7 | * You may obtain a copy of the License at http://www.mozilla.org/MPL/ | |
8 | * | |
9 | * Software distributed under the License is distributed on an "AS IS" basis, | |
10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | |
11 | * for the specific language governing rights and limitations under the License. | |
12 | * | |
13 | * The Original Code is 'iText, a free JAVA-PDF library'. | |
14 | * | |
15 | * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by | |
16 | * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. | |
17 | * All Rights Reserved. | |
18 | * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer | |
19 | * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. | |
20 | * | |
21 | * Contributor(s): all the names of the contributors are added in the source code | |
22 | * where applicable. | |
23 | * | |
24 | * Alternatively, the contents of this file may be used under the terms of the | |
25 | * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the | |
26 | * provisions of LGPL are applicable instead of those above. If you wish to | |
27 | * allow use of your version of this file only under the terms of the LGPL | |
28 | * License and not to allow others to use your version of this file under | |
29 | * the MPL, indicate your decision by deleting the provisions above and | |
30 | * replace them with the notice and other provisions required by the LGPL. | |
31 | * If you do not delete the provisions above, a recipient may use your version | |
32 | * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. | |
33 | * | |
34 | * This library is free software; you can redistribute it and/or modify it | |
35 | * under the terms of the MPL as stated above or under the terms of the GNU | |
36 | * Library General Public License as published by the Free Software Foundation; | |
37 | * either version 2 of the License, or any later version. | |
38 | * | |
39 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
40 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
41 | * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more | |
42 | * details. | |
43 | * | |
44 | * If you didn't download this code from the following link, you should check if | |
45 | * you aren't using an obsolete version: | |
46 | * http://www.lowagie.com/iText/ | |
47 | */ | |
48 | package com.lowagie.text.pdf; | |
49 | import java.awt.Color; | |
50 | import java.util.ArrayList; | |
51 | import java.util.Iterator; | |
52 | import com.lowagie.text.error_messages.MessageLocalization; | |
53 | ||
54 | import com.lowagie.text.Chunk; | |
55 | import com.lowagie.text.Element; | |
56 | import com.lowagie.text.Phrase; | |
57 | ||
58 | /** Writes text vertically. Note that the naming is done according | |
59 | * to horizontal text although it refers to vertical text. | |
60 | * A line with the alignment Element.LEFT_ALIGN will actually | |
61 | * be top aligned. | |
62 | */ | |
63 | public class VerticalText { | |
64 | ||
65 | /** Signals that there are no more text available. */ | |
66 | public static final int NO_MORE_TEXT = 1; | |
67 | | |
68 | /** Signals that there is no more column. */ | |
69 | public static final int NO_MORE_COLUMN = 2; | |
70 | ||
71 | /** The chunks that form the text. */ | |
72 | protected ArrayList chunks = new ArrayList(); | |
73 | ||
74 | /** The <CODE>PdfContent</CODE> where the text will be written to. */ | |
75 | protected PdfContentByte text; | |
76 | | |
77 | /** The column alignment. Default is left alignment. */ | |
78 | protected int alignment = Element.ALIGN_LEFT; | |
79 | ||
80 | /** Marks the chunks to be eliminated when the line is written. */ | |
81 | protected int currentChunkMarker = -1; | |
82 | | |
83 | /** The chunk created by the splitting. */ | |
84 | protected PdfChunk currentStandbyChunk; | |
85 | | |
86 | /** The chunk created by the splitting. */ | |
87 | protected String splittedChunkText; | |
88 | ||
89 | /** The leading | |
90 | */ | |
91 | protected float leading; | |
92 | | |
93 | /** The X coordinate. | |
94 | */ | |
95 | protected float startX; | |
96 | | |
97 | /** The Y coordinate. | |
98 | */ | |
99 | protected float startY; | |
100 | | |
101 | /** The maximum number of vertical lines. | |
102 | */ | |
103 | protected int maxLines; | |
104 | | |
105 | /** The height of the text. | |
106 | */ | |
107 | protected float height; | |
108 | | |
109 | /** Creates new VerticalText | |
110 | * @param text the place where the text will be written to. Can | |
111 | * be a template. | |
112 | */ | |
113 | public VerticalText(PdfContentByte text) { | |
114 | this.text = text; | |
115 | } | |
116 | | |
117 | /** | |
118 | * Adds a <CODE>Phrase</CODE> to the current text array. | |
119 | * @param phrase the text | |
120 | */ | |
121 | public void addText(Phrase phrase) { | |
122 | for (Object o : phrase.getChunks()) { | |
123 | chunks.add(new PdfChunk((Chunk) o, null)); | |
124 | } | |
125 | } | |
126 | | |
127 | /** | |
128 | * Adds a <CODE>Chunk</CODE> to the current text array. | |
129 | * @param chunk the text | |
130 | */ | |
131 | public void addText(Chunk chunk) { | |
132 | chunks.add(new PdfChunk(chunk, null)); | |
133 | } | |
134 | ||
135 | /** Sets the layout. | |
136 | * @param startX the top right X line position | |
137 | * @param startY the top right Y line position | |
138 | * @param height the height of the lines | |
139 | * @param maxLines the maximum number of lines | |
140 | * @param leading the separation between the lines | |
141 | */ | |
142 | public void setVerticalLayout(float startX, float startY, float height, int maxLines, float leading) { | |
143 | this.startX = startX; | |
144 | this.startY = startY; | |
145 | this.height = height; | |
146 | this.maxLines = maxLines; | |
147 |
1
1. setVerticalLayout : removed call to com/lowagie/text/pdf/VerticalText::setLeading → NO_COVERAGE |
setLeading(leading); |
148 | } | |
149 | | |
150 | /** Sets the separation between the vertical lines. | |
151 | * @param leading the vertical line separation | |
152 | */ | |
153 | public void setLeading(float leading) { | |
154 | this.leading = leading; | |
155 | } | |
156 | ||
157 | /** Gets the separation between the vertical lines. | |
158 | * @return the vertical line separation | |
159 | */ | |
160 | public float getLeading() { | |
161 | return leading; | |
162 | } | |
163 | | |
164 | /** | |
165 | * Creates a line from the chunk array. | |
166 | * @param width the width of the line | |
167 | * @return the line or null if no more chunks | |
168 | */ | |
169 | protected PdfLine createLine(float width) { | |
170 |
1
1. createLine : negated conditional → NO_COVERAGE |
if (chunks.isEmpty()) |
171 |
1
1. createLine : mutated return of Object value for com/lowagie/text/pdf/VerticalText::createLine to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return null; |
172 | splittedChunkText = null; | |
173 | currentStandbyChunk = null; | |
174 | PdfLine line = new PdfLine(0, width, alignment, 0); | |
175 | String total; | |
176 |
3
1. createLine : changed conditional boundary → NO_COVERAGE 2. createLine : Replaced integer addition with subtraction → NO_COVERAGE 3. createLine : negated conditional → NO_COVERAGE |
for (currentChunkMarker = 0; currentChunkMarker < chunks.size(); ++currentChunkMarker) { |
177 | PdfChunk original = (PdfChunk)(chunks.get(currentChunkMarker)); | |
178 | total = original.toString(); | |
179 | currentStandbyChunk = line.add(original); | |
180 |
1
1. createLine : negated conditional → NO_COVERAGE |
if (currentStandbyChunk != null) { |
181 | splittedChunkText = original.toString(); | |
182 |
1
1. createLine : removed call to com/lowagie/text/pdf/PdfChunk::setValue → NO_COVERAGE |
original.setValue(total); |
183 |
1
1. createLine : mutated return of Object value for com/lowagie/text/pdf/VerticalText::createLine to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return line; |
184 | } | |
185 | } | |
186 |
1
1. createLine : mutated return of Object value for com/lowagie/text/pdf/VerticalText::createLine to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return line; |
187 | } | |
188 | | |
189 | /** | |
190 | * Normalizes the list of chunks when the line is accepted. | |
191 | */ | |
192 | protected void shortenChunkArray() { | |
193 |
2
1. shortenChunkArray : changed conditional boundary → NO_COVERAGE 2. shortenChunkArray : negated conditional → NO_COVERAGE |
if (currentChunkMarker < 0) |
194 | return; | |
195 |
2
1. shortenChunkArray : changed conditional boundary → NO_COVERAGE 2. shortenChunkArray : negated conditional → NO_COVERAGE |
if (currentChunkMarker >= chunks.size()) { |
196 |
1
1. shortenChunkArray : removed call to java/util/ArrayList::clear → NO_COVERAGE |
chunks.clear(); |
197 | return; | |
198 | } | |
199 | PdfChunk split = (PdfChunk)(chunks.get(currentChunkMarker)); | |
200 |
1
1. shortenChunkArray : removed call to com/lowagie/text/pdf/PdfChunk::setValue → NO_COVERAGE |
split.setValue(splittedChunkText); |
201 | chunks.set(currentChunkMarker, currentStandbyChunk); | |
202 |
2
1. shortenChunkArray : changed conditional boundary → NO_COVERAGE 2. shortenChunkArray : negated conditional → NO_COVERAGE |
if (currentChunkMarker > 0) { |
203 |
1
1. shortenChunkArray : removed call to java/util/List::clear → NO_COVERAGE |
chunks.subList(0, currentChunkMarker).clear(); |
204 | } | |
205 | } | |
206 | ||
207 | /** | |
208 | * Outputs the lines to the document. It is equivalent to <CODE>go(false)</CODE>. | |
209 | * @return returns the result of the operation. It can be <CODE>NO_MORE_TEXT</CODE> | |
210 | * and/or <CODE>NO_MORE_COLUMN</CODE> | |
211 | */ | |
212 | public int go() { | |
213 |
1
1. go : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return go(false); |
214 | } | |
215 | | |
216 | /** | |
217 | * Outputs the lines to the document. The output can be simulated. | |
218 | * @param simulate <CODE>true</CODE> to simulate the writing to the document | |
219 | * @return returns the result of the operation. It can be <CODE>NO_MORE_TEXT</CODE> | |
220 | * and/or <CODE>NO_MORE_COLUMN</CODE> | |
221 | */ | |
222 | public int go(boolean simulate) { | |
223 | boolean dirty = false; | |
224 | PdfContentByte graphics = null; | |
225 |
1
1. go : negated conditional → NO_COVERAGE |
if (text != null) { |
226 | graphics = text.getDuplicate(); | |
227 | } | |
228 |
1
1. go : negated conditional → NO_COVERAGE |
else if (!simulate) |
229 | throw new NullPointerException(MessageLocalization.getComposedMessage("verticaltext.go.with.simulate.eq.eq.false.and.text.eq.eq.null")); | |
230 | int status = 0; | |
231 | for (;;) { | |
232 |
2
1. go : changed conditional boundary → NO_COVERAGE 2. go : negated conditional → NO_COVERAGE |
if (maxLines <= 0) { |
233 | status = NO_MORE_COLUMN; | |
234 |
1
1. go : negated conditional → NO_COVERAGE |
if (chunks.isEmpty()) |
235 |
1
1. go : Replaced bitwise OR with AND → NO_COVERAGE |
status |= NO_MORE_TEXT; |
236 | break; | |
237 | } | |
238 |
1
1. go : negated conditional → NO_COVERAGE |
if (chunks.isEmpty()) { |
239 | status = NO_MORE_TEXT; | |
240 | break; | |
241 | } | |
242 | PdfLine line = createLine(height); | |
243 |
2
1. go : negated conditional → NO_COVERAGE 2. go : negated conditional → NO_COVERAGE |
if (!simulate && !dirty) { |
244 |
1
1. go : removed call to com/lowagie/text/pdf/PdfContentByte::beginText → NO_COVERAGE |
text.beginText(); |
245 | dirty = true; | |
246 | } | |
247 |
1
1. go : removed call to com/lowagie/text/pdf/VerticalText::shortenChunkArray → NO_COVERAGE |
shortenChunkArray(); |
248 |
1
1. go : negated conditional → NO_COVERAGE |
if (!simulate) { |
249 |
2
1. go : Replaced float subtraction with addition → NO_COVERAGE 2. go : removed call to com/lowagie/text/pdf/PdfContentByte::setTextMatrix → NO_COVERAGE |
text.setTextMatrix(startX, startY - line.indentLeft()); |
250 |
1
1. go : removed call to com/lowagie/text/pdf/VerticalText::writeLine → NO_COVERAGE |
writeLine(line, text, graphics); |
251 | } | |
252 |
1
1. go : Replaced integer subtraction with addition → NO_COVERAGE |
--maxLines; |
253 |
1
1. go : Replaced float subtraction with addition → NO_COVERAGE |
startX -= leading; |
254 | } | |
255 |
1
1. go : negated conditional → NO_COVERAGE |
if (dirty) { |
256 |
1
1. go : removed call to com/lowagie/text/pdf/PdfContentByte::endText → NO_COVERAGE |
text.endText(); |
257 |
1
1. go : removed call to com/lowagie/text/pdf/PdfContentByte::add → NO_COVERAGE |
text.add(graphics); |
258 | } | |
259 |
1
1. go : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return status; |
260 | } | |
261 | | |
262 | void writeLine(PdfLine line, PdfContentByte text, PdfContentByte graphics) { | |
263 | PdfFont currentFont = null; | |
264 | PdfChunk chunk; | |
265 |
1
1. writeLine : negated conditional → NO_COVERAGE |
for (Iterator j = line.iterator(); j.hasNext(); ) { |
266 | chunk = (PdfChunk) j.next(); | |
267 | | |
268 |
1
1. writeLine : negated conditional → NO_COVERAGE |
if (chunk.font().compareTo(currentFont) != 0) { |
269 | currentFont = chunk.font(); | |
270 |
1
1. writeLine : removed call to com/lowagie/text/pdf/PdfContentByte::setFontAndSize → NO_COVERAGE |
text.setFontAndSize(currentFont.getFont(), currentFont.size()); |
271 | } | |
272 | Color color = chunk.color(); | |
273 |
1
1. writeLine : negated conditional → NO_COVERAGE |
if (color != null) |
274 |
1
1. writeLine : removed call to com/lowagie/text/pdf/PdfContentByte::setColorFill → NO_COVERAGE |
text.setColorFill(color); |
275 |
1
1. writeLine : removed call to com/lowagie/text/pdf/PdfContentByte::showText → NO_COVERAGE |
text.showText(chunk.toString()); |
276 |
1
1. writeLine : negated conditional → NO_COVERAGE |
if (color != null) |
277 |
1
1. writeLine : removed call to com/lowagie/text/pdf/PdfContentByte::resetRGBColorFill → NO_COVERAGE |
text.resetRGBColorFill(); |
278 | } | |
279 | } | |
280 | | |
281 | /** Sets the new text origin. | |
282 | * @param startX the X coordinate | |
283 | * @param startY the Y coordinate | |
284 | */ | |
285 | public void setOrigin(float startX, float startY) { | |
286 | this.startX = startX; | |
287 | this.startY = startY; | |
288 | } | |
289 | | |
290 | /** Gets the X coordinate where the next line will be written. This value will change | |
291 | * after each call to <code>go()</code>. | |
292 | * @return the X coordinate | |
293 | */ | |
294 | public float getOriginX() { | |
295 | return startX; | |
296 | } | |
297 | ||
298 | /** Gets the Y coordinate where the next line will be written. | |
299 | * @return the Y coordinate | |
300 | */ | |
301 | public float getOriginY() { | |
302 | return startY; | |
303 | } | |
304 | | |
305 | /** Gets the maximum number of available lines. This value will change | |
306 | * after each call to <code>go()</code>. | |
307 | * @return Value of property maxLines. | |
308 | */ | |
309 | public int getMaxLines() { | |
310 | return maxLines; | |
311 | } | |
312 | | |
313 | /** Sets the maximum number of lines. | |
314 | * @param maxLines the maximum number of lines | |
315 | */ | |
316 | public void setMaxLines(int maxLines) { | |
317 | this.maxLines = maxLines; | |
318 | } | |
319 | | |
320 | /** Gets the height of the line | |
321 | * @return the height | |
322 | */ | |
323 | public float getHeight() { | |
324 | return height; | |
325 | } | |
326 | | |
327 | /** Sets the height of the line | |
328 | * @param height the new height | |
329 | */ | |
330 | public void setHeight(float height) { | |
331 | this.height = height; | |
332 | } | |
333 | | |
334 | /** | |
335 | * Sets the alignment. | |
336 | * @param alignment the alignment | |
337 | */ | |
338 | public void setAlignment(int alignment) { | |
339 | this.alignment = alignment; | |
340 | } | |
341 | | |
342 | /** | |
343 | * Gets the alignment. | |
344 | * @return the alignment | |
345 | */ | |
346 | public int getAlignment() { | |
347 | return alignment; | |
348 | } | |
349 | } | |
Mutations | ||
147 |
1.1 |
|
170 |
1.1 |
|
171 |
1.1 |
|
176 |
1.1 2.2 3.3 |
|
180 |
1.1 |
|
182 |
1.1 |
|
183 |
1.1 |
|
186 |
1.1 |
|
193 |
1.1 2.2 |
|
195 |
1.1 2.2 |
|
196 |
1.1 |
|
200 |
1.1 |
|
202 |
1.1 2.2 |
|
203 |
1.1 |
|
213 |
1.1 |
|
225 |
1.1 |
|
228 |
1.1 |
|
232 |
1.1 2.2 |
|
234 |
1.1 |
|
235 |
1.1 |
|
238 |
1.1 |
|
243 |
1.1 2.2 |
|
244 |
1.1 |
|
247 |
1.1 |
|
248 |
1.1 |
|
249 |
1.1 2.2 |
|
250 |
1.1 |
|
252 |
1.1 |
|
253 |
1.1 |
|
255 |
1.1 |
|
256 |
1.1 |
|
257 |
1.1 |
|
259 |
1.1 |
|
265 |
1.1 |
|
268 |
1.1 |
|
270 |
1.1 |
|
273 |
1.1 |
|
274 |
1.1 |
|
275 |
1.1 |
|
276 |
1.1 |
|
277 |
1.1 |