MultiColumnText.java

1
/*
2
 * $Id: MultiColumnText.java 4065 2009-09-16 23:09:11Z psoares33 $
3
 *
4
 * Copyright 2004 Steve Appling
5
 *
6
 * The contents of this file are subject to the Mozilla Public License Version 1.1
7
 * (the "License"); you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at http://www.mozilla.org/MPL/
9
 *
10
 * Software distributed under the License is distributed on an "AS IS" basis,
11
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12
 * for the specific language governing rights and limitations under the License.
13
 *
14
 * The Original Code is 'iText, a free JAVA-PDF library'.
15
 *
16
 * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
17
 * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie.
18
 * All Rights Reserved.
19
 * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
20
 * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved.
21
 *
22
 * Contributor(s): all the names of the contributors are added in the source code
23
 * where applicable.
24
 *
25
 * Alternatively, the contents of this file may be used under the terms of the
26
 * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
27
 * provisions of LGPL are applicable instead of those above.  If you wish to
28
 * allow use of your version of this file only under the terms of the LGPL
29
 * License and not to allow others to use your version of this file under
30
 * the MPL, indicate your decision by deleting the provisions above and
31
 * replace them with the notice and other provisions required by the LGPL.
32
 * If you do not delete the provisions above, a recipient may use your version
33
 * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
34
 *
35
 * This library is free software; you can redistribute it and/or modify it
36
 * under the terms of the MPL as stated above or under the terms of the GNU
37
 * Library General Public License as published by the Free Software Foundation;
38
 * either version 2 of the License, or any later version.
39
 *
40
 * This library is distributed in the hope that it will be useful, but WITHOUT
41
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
42
 * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
43
 * details.
44
 *
45
 * If you didn't download this code from the following link, you should check if
46
 * you aren't using an obsolete version:
47
 * http://www.lowagie.com/iText/
48
 */
49
50
package com.lowagie.text.pdf;
51
52
import java.util.ArrayList;
53
import com.lowagie.text.error_messages.MessageLocalization;
54
55
import com.lowagie.text.Chunk;
56
import com.lowagie.text.DocumentException;
57
import com.lowagie.text.Element;
58
import com.lowagie.text.ElementListener;
59
import com.lowagie.text.Phrase;
60
import com.lowagie.text.Rectangle;
61
62
/**
63
 * Formats content into one or more columns bounded by a
64
 * rectangle.  The columns may be simple rectangles or
65
 * more complicated shapes. Add all of the columns before
66
 * adding content. Column continuation is supported. A MultiColumnText object may be added to
67
 * a document using <CODE>Document.add</CODE>.
68
 * @author Steve Appling
69
 */
70
public class MultiColumnText implements Element {
71
72
    /** special constant for automatic calculation of height */
73
    public static final float AUTOMATIC = -1f;
74
75
    /**
76
     * total desiredHeight of columns.  If <CODE>AUTOMATIC</CODE>, this means fill pages until done.
77
     * This may be larger than one page
78
     */
79
    private float desiredHeight;
80
81
    /**
82
     * total height of element written out so far
83
     */
84
    private float totalHeight;
85
86
    /**
87
     * true if all the text could not be written out due to height restriction
88
     */
89
    private boolean overflow;
90
91
    /**
92
     * Top of the columns - y position on starting page.
93
     * If <CODE>AUTOMATIC</CODE>, it means current y position when added to document
94
     */
95
    private float top;
96
97
    /**
98
     * ColumnText object used to do all the real work.  This same object is used for all columns
99
     */
100
    private ColumnText columnText;
101
102
    /**
103
     * Array of <CODE>ColumnDef</CODE> objects used to define the columns
104
     */
105
    private ArrayList columnDefs;
106
107
    /**
108
     * true if all columns are simple (rectangular)
109
     */
110
    private boolean simple = true;
111
112
    private int currentColumn = 0;
113
    
114
    private float nextY = AUTOMATIC;
115
    
116
    private boolean columnsRightToLeft = false;
117
    
118
    private PdfDocument document;
119
    /**
120
     * Default constructor.  Sets height to <CODE>AUTOMATIC</CODE>.
121
     * Columns will repeat on each page as necessary to accommodate content length.
122
     */
123
    public MultiColumnText() {
124
        this(AUTOMATIC);
125
    }
126
127
    /**
128
     * Construct a MultiColumnText container of the specified height.
129
     * If height is <CODE>AUTOMATIC</CODE>, fill complete pages until done.
130
     * If a specific height is used, it may span one or more pages.
131
     *
132
     * @param height
133
     */
134
    public MultiColumnText(float height) {
135
        columnDefs = new ArrayList();
136
        desiredHeight = height;
137
        top = AUTOMATIC;
138
        // canvas will be set later
139
        columnText = new ColumnText(null);
140
        totalHeight = 0f;
141
    }
142
143
    /**
144
     * Construct a MultiColumnText container of the specified height
145
     * starting at the specified Y position.
146
     *
147
     * @param height
148
     * @param top
149
     */
150
    public MultiColumnText(float top, float height) {
151
        columnDefs = new ArrayList();
152
        desiredHeight = height;
153
        this.top = top;
154
        nextY = top;
155
        // canvas will be set later
156
        columnText = new ColumnText(null);
157
        totalHeight = 0f;
158
    }
159
    
160
    /**
161
     * Indicates that all of the text did not fit in the
162
     * specified height. Note that isOverflow will return
163
     * false before the MultiColumnText object has been
164
     * added to the document.  It will always be false if
165
     * the height is AUTOMATIC.
166
     *
167
     * @return true if there is still space left in the column
168
     */
169
    public boolean isOverflow() {
170
        return overflow;
171
    }
172
173
    /**
174
     * Copy the parameters from the specified ColumnText to use
175
     * when rendering.  Parameters like <CODE>setArabicOptions</CODE>
176
     * must be set in this way.
177
     *
178
     * @param sourceColumn
179
     */
180
    public void useColumnParams(ColumnText sourceColumn) {
181
        // note that canvas will be overwritten later
182
        columnText.setSimpleVars(sourceColumn);
183
    }
184
185
    /**
186
     * Add a new column.  The parameters are limits for each column
187
     * wall in the format of a sequence of points (x1,y1,x2,y2,...).
188
     *
189
     * @param left  limits for left column
190
     * @param right limits for right column
191
     */
192
    public void addColumn(float[] left, float[] right) {
193
        ColumnDef nextDef = new ColumnDef(left, right);
194 1 1. addColumn : negated conditional → NO_COVERAGE
        if (!nextDef.isSimple()) simple = false;
195
        columnDefs.add(nextDef);
196
    }
197
198
    /**
199
     * Add a simple rectangular column with specified left
200
     * and right x position boundaries.
201
     *
202
     * @param left  left boundary
203
     * @param right right boundary
204
     */
205
    public void addSimpleColumn(float left, float right) {
206
        ColumnDef newCol = new ColumnDef(left, right);
207
        columnDefs.add(newCol);
208
    }
209
210
    /**
211
     * Add the specified number of evenly spaced rectangular columns.
212
     * Columns will be separated by the specified gutterWidth.
213
     *
214
     * @param left        left boundary of first column
215
     * @param right       right boundary of last column
216
     * @param gutterWidth width of gutter spacing between columns
217
     * @param numColumns  number of columns to add
218
     */
219
    public void addRegularColumns(float left, float right, float gutterWidth, int numColumns) {
220
        float currX = left;
221 1 1. addRegularColumns : Replaced float subtraction with addition → NO_COVERAGE
        float width = right - left;
222 4 1. addRegularColumns : Replaced integer subtraction with addition → NO_COVERAGE
2. addRegularColumns : Replaced float multiplication with division → NO_COVERAGE
3. addRegularColumns : Replaced float subtraction with addition → NO_COVERAGE
4. addRegularColumns : Replaced float division with multiplication → NO_COVERAGE
        float colWidth = (width - (gutterWidth * (numColumns - 1))) / numColumns;
223 3 1. addRegularColumns : changed conditional boundary → NO_COVERAGE
2. addRegularColumns : Changed increment from 1 to -1 → NO_COVERAGE
3. addRegularColumns : negated conditional → NO_COVERAGE
        for (int i = 0; i < numColumns; i++) {
224 2 1. addRegularColumns : Replaced float addition with subtraction → NO_COVERAGE
2. addRegularColumns : removed call to com/lowagie/text/pdf/MultiColumnText::addSimpleColumn → NO_COVERAGE
            addSimpleColumn(currX, currX + colWidth);
225 2 1. addRegularColumns : Replaced float addition with subtraction → NO_COVERAGE
2. addRegularColumns : Replaced float addition with subtraction → NO_COVERAGE
            currX += colWidth + gutterWidth;
226
        }
227
    }
228
229
    /**
230
     * Adds a <CODE>Phrase</CODE> to the current text array.
231
     * Will not have any effect if addElement() was called before.
232
     * @param phrase the text
233
     * @since    2.1.5
234
     */
235
    public void addText(Phrase phrase) {
236
        columnText.addText(phrase);
237
    }
238
    
239
    /**
240
     * Adds a <CODE>Chunk</CODE> to the current text array.
241
     * Will not have any effect if addElement() was called before.
242
     * @param chunk the text
243
     * @since    2.1.5
244
     */
245
    public void addText(Chunk chunk) {
246
        columnText.addText(chunk);
247
    }
248
    
249
    /**
250
     * Add an element to be rendered in a column.
251
     * Note that you can only add a <CODE>Phrase</CODE>
252
     * or a <CODE>Chunk</CODE> if the columns are
253
     * not all simple.  This is an underlying restriction in
254
     * {@link com.lowagie.text.pdf.ColumnText}
255
     *
256
     * @param element element to add
257
     * @throws DocumentException if element can't be added
258
     */
259
    public void addElement(Element element) throws DocumentException {
260 1 1. addElement : negated conditional → NO_COVERAGE
        if (simple) {
261 1 1. addElement : removed call to com/lowagie/text/pdf/ColumnText::addElement → NO_COVERAGE
            columnText.addElement(element);
262 1 1. addElement : negated conditional → NO_COVERAGE
        } else if (element instanceof Phrase) {
263 1 1. addElement : removed call to com/lowagie/text/pdf/ColumnText::addText → NO_COVERAGE
            columnText.addText((Phrase) element);
264 1 1. addElement : negated conditional → NO_COVERAGE
        } else if (element instanceof Chunk) {
265 1 1. addElement : removed call to com/lowagie/text/pdf/ColumnText::addText → NO_COVERAGE
            columnText.addText((Chunk) element);
266
        } else {
267
            throw new DocumentException(MessageLocalization.getComposedMessage("can.t.add.1.to.multicolumntext.with.complex.columns", element.getClass()));
268
        }
269
    }
270
271
272
    /**
273
     * Write out the columns.  After writing, use
274
     * {@link #isOverflow()} to see if all text was written.
275
     * @param canvas PdfContentByte to write with
276
     * @param document document to write to (only used to get page limit info)
277
     * @param documentY starting y position to begin writing at
278
     * @return the current height (y position) after writing the columns
279
     * @throws DocumentException on error
280
     */
281
    public float write(PdfContentByte canvas, PdfDocument document, float documentY) throws DocumentException {
282
        this.document = document;
283 1 1. write : removed call to com/lowagie/text/pdf/ColumnText::setCanvas → NO_COVERAGE
        columnText.setCanvas(canvas);
284 1 1. write : negated conditional → NO_COVERAGE
        if (columnDefs.isEmpty()) {
285
            throw new DocumentException(MessageLocalization.getComposedMessage("multicolumntext.has.no.columns"));
286
        }
287
        overflow = false;
288
        float currentHeight = 0;
289
        boolean done = false;
290
        try {
291 1 1. write : negated conditional → NO_COVERAGE
            while (!done) {
292 1 1. write : negated conditional → NO_COVERAGE
                if (top == AUTOMATIC) {
293
                    top = document.getVerticalPosition(true); // RS - 07/07/2005 - Get current doc writing position for top of columns on new page.
294
                }
295 1 1. write : negated conditional → NO_COVERAGE
                else if (nextY == AUTOMATIC) {
296
                    nextY = document.getVerticalPosition(true); // RS - 07/07/2005 - - Get current doc writing position for top of columns on new page.
297
                }
298
                ColumnDef currentDef = (ColumnDef) columnDefs.get(getCurrentColumn());
299 1 1. write : removed call to com/lowagie/text/pdf/ColumnText::setYLine → NO_COVERAGE
                columnText.setYLine(top);
300
301
                float[] left = currentDef.resolvePositions(Rectangle.LEFT);
302
                float[] right = currentDef.resolvePositions(Rectangle.RIGHT);
303 3 1. write : Replaced integer modulus with multiplication → NO_COVERAGE
2. write : negated conditional → NO_COVERAGE
3. write : negated conditional → NO_COVERAGE
                if (document.isMarginMirroring() && document.getPageNumber() % 2 == 0){
304 1 1. write : Replaced float subtraction with addition → NO_COVERAGE
                    float delta = document.rightMargin() - document.left();
305
                    left = left.clone();
306
                    right = right.clone();
307 2 1. write : changed conditional boundary → NO_COVERAGE
2. write : negated conditional → NO_COVERAGE
                    for (int i = 0; i < left.length; i += 2) {
308 1 1. write : Replaced float subtraction with addition → NO_COVERAGE
                        left[i] -= delta;
309
                    }
310 2 1. write : changed conditional boundary → NO_COVERAGE
2. write : negated conditional → NO_COVERAGE
                    for (int i = 0; i < right.length; i += 2) {
311 1 1. write : Replaced float subtraction with addition → NO_COVERAGE
                        right[i] -= delta;
312
                    }
313
                }
314
                
315
                currentHeight = Math.max(currentHeight, getHeight(left, right));
316
317 1 1. write : negated conditional → NO_COVERAGE
                if (currentDef.isSimple()) {
318 1 1. write : removed call to com/lowagie/text/pdf/ColumnText::setSimpleColumn → NO_COVERAGE
                    columnText.setSimpleColumn(left[2], left[3], right[0], right[1]);
319
                } else {
320 1 1. write : removed call to com/lowagie/text/pdf/ColumnText::setColumns → NO_COVERAGE
                    columnText.setColumns(left, right);
321
                }
322
323
                int result = columnText.go();
324 2 1. write : Replaced bitwise AND with OR → NO_COVERAGE
2. write : negated conditional → NO_COVERAGE
                if ((result & ColumnText.NO_MORE_TEXT) != 0) {
325
                    done = true;
326
                    top = columnText.getYLine();
327 1 1. write : negated conditional → NO_COVERAGE
                } else if (shiftCurrentColumn()) {
328
                    top = nextY;
329
                } else {  // check if we are done because of height
330 1 1. write : Replaced float addition with subtraction → NO_COVERAGE
                    totalHeight += currentHeight;
331 3 1. write : changed conditional boundary → NO_COVERAGE
2. write : negated conditional → NO_COVERAGE
3. write : negated conditional → NO_COVERAGE
                    if ((desiredHeight != AUTOMATIC) && (totalHeight >= desiredHeight)) {
332
                        overflow = true;
333
                        break;
334
                    } else {  // need to start new page and reset the columns
335
                        documentY = nextY;
336 1 1. write : removed call to com/lowagie/text/pdf/MultiColumnText::newPage → NO_COVERAGE
                        newPage();
337
                        currentHeight = 0;
338
                    }
339
                }
340
            }
341
        } catch (DocumentException ex) {
342 1 1. write : removed call to com/lowagie/text/DocumentException::printStackTrace → NO_COVERAGE
            ex.printStackTrace();
343
            throw ex;
344
        }
345 2 1. write : negated conditional → NO_COVERAGE
2. write : negated conditional → NO_COVERAGE
        if (desiredHeight == AUTOMATIC && columnDefs.size() == 1) {
346 1 1. write : Replaced float subtraction with addition → NO_COVERAGE
            currentHeight = documentY - columnText.getYLine();
347
        }
348 1 1. write : replaced return of float value with -(x + 1) for com/lowagie/text/pdf/MultiColumnText::write → NO_COVERAGE
        return currentHeight;
349
    }
350
351
    private void newPage() throws DocumentException {
352 1 1. newPage : removed call to com/lowagie/text/pdf/MultiColumnText::resetCurrentColumn → NO_COVERAGE
        resetCurrentColumn();
353 1 1. newPage : negated conditional → NO_COVERAGE
        if (desiredHeight == AUTOMATIC) {
354
            top = nextY = AUTOMATIC;
355
        }
356
        else {
357
            top = nextY;
358
        }
359
        totalHeight = 0;
360 1 1. newPage : negated conditional → NO_COVERAGE
        if (document != null) {
361
            document.newPage();
362
        }
363
    }
364
    
365
    /**
366
     * Figure out the height of a column from the border extents
367
     *
368
     * @param left  left border
369
     * @param right right border
370
     * @return height
371
     */
372
    private float getHeight(float[] left, float[] right) {
373
        float max = Float.MIN_VALUE;
374
        float min = Float.MAX_VALUE;
375 2 1. getHeight : changed conditional boundary → NO_COVERAGE
2. getHeight : negated conditional → NO_COVERAGE
        for (int i = 0; i < left.length; i += 2) {
376 1 1. getHeight : Replaced integer addition with subtraction → NO_COVERAGE
            min = Math.min(min, left[i + 1]);
377 1 1. getHeight : Replaced integer addition with subtraction → NO_COVERAGE
            max = Math.max(max, left[i + 1]);
378
        }
379 2 1. getHeight : changed conditional boundary → NO_COVERAGE
2. getHeight : negated conditional → NO_COVERAGE
        for (int i = 0; i < right.length; i += 2) {
380 1 1. getHeight : Replaced integer addition with subtraction → NO_COVERAGE
            min = Math.min(min, right[i + 1]);
381 1 1. getHeight : Replaced integer addition with subtraction → NO_COVERAGE
            max = Math.max(max, right[i + 1]);
382
        }
383 2 1. getHeight : Replaced float subtraction with addition → NO_COVERAGE
2. getHeight : replaced return of float value with -(x + 1) for com/lowagie/text/pdf/MultiColumnText::getHeight → NO_COVERAGE
        return max - min;
384
    }
385
386
387
    /**
388
     * Processes the element by adding it to an
389
     * <CODE>ElementListener</CODE>.
390
     *
391
     * @param    listener    an <CODE>ElementListener</CODE>
392
     * @return    <CODE>true</CODE> if the element was processed successfully
393
     */
394
    public boolean process(ElementListener listener) {
395
        try {
396 1 1. process : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE
            return listener.add(this);
397
        } catch (DocumentException de) {
398 1 1. process : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE
            return false;
399
        }
400
    }
401
402
    /**
403
     * Gets the type of the text element.
404
     *
405
     * @return    a type
406
     */
407
408
    public int type() {
409
        return Element.MULTI_COLUMN_TEXT;
410
    }
411
412
    /**
413
     * Returns null - not used
414
     *
415
     * @return    null
416
     */
417
418
    public ArrayList getChunks() {
419
        return null;
420
    }
421
    
422
    /**
423
     * @see com.lowagie.text.Element#isContent()
424
     * @since    iText 2.0.8
425
     */
426
    public boolean isContent() {
427
        return true;
428
    }
429
430
    /**
431
     * @see com.lowagie.text.Element#isNestable()
432
     * @since    iText 2.0.8
433
     */
434
    public boolean isNestable() {
435
        return false;
436
    }
437
438
    /**
439
     * Calculates the appropriate y position for the bottom
440
     * of the columns on this page.
441
     *
442
     * @return the y position of the bottom of the columns
443
     */
444
    private float getColumnBottom() {
445 1 1. getColumnBottom : negated conditional → NO_COVERAGE
        if (desiredHeight == AUTOMATIC) {
446 1 1. getColumnBottom : replaced return of float value with -(x + 1) for com/lowagie/text/pdf/MultiColumnText::getColumnBottom → NO_COVERAGE
            return document.bottom();
447
        } else {
448 3 1. getColumnBottom : Replaced float subtraction with addition → NO_COVERAGE
2. getColumnBottom : Replaced float subtraction with addition → NO_COVERAGE
3. getColumnBottom : replaced return of float value with -(x + 1) for com/lowagie/text/pdf/MultiColumnText::getColumnBottom → NO_COVERAGE
            return Math.max(top - (desiredHeight - totalHeight), document.bottom());
449
        }
450
    }
451
452
    /**
453
     * Moves the text insertion point to the beginning of the next column, issuing a page break if
454
     * needed.
455
     * @throws DocumentException on error
456
     */    
457
    public void nextColumn() throws DocumentException {
458 2 1. nextColumn : Replaced integer addition with subtraction → NO_COVERAGE
2. nextColumn : Replaced integer modulus with multiplication → NO_COVERAGE
        currentColumn = (currentColumn + 1) % columnDefs.size();
459
        top = nextY;
460 1 1. nextColumn : negated conditional → NO_COVERAGE
        if (currentColumn == 0) {
461 1 1. nextColumn : removed call to com/lowagie/text/pdf/MultiColumnText::newPage → NO_COVERAGE
            newPage();
462
        }
463
    }
464
465
    /**
466
     * Gets the current column.
467
     * @return the current column
468
     */
469
    public int getCurrentColumn() {
470 1 1. getCurrentColumn : negated conditional → NO_COVERAGE
        if (columnsRightToLeft) {
471 3 1. getCurrentColumn : Replaced integer subtraction with addition → NO_COVERAGE
2. getCurrentColumn : Replaced integer subtraction with addition → NO_COVERAGE
3. getCurrentColumn : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE
            return (columnDefs.size() - currentColumn - 1);
472
        } 
473 1 1. getCurrentColumn : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE
        return currentColumn;
474
    }
475
    
476
    /**
477
     * Resets the current column.
478
     */
479
    public void resetCurrentColumn() {
480
        currentColumn = 0;
481
    }
482
    
483
    /**
484
     * Shifts the current column.
485
     * @return true if the current column has changed
486
     */
487
    public boolean shiftCurrentColumn() {
488 3 1. shiftCurrentColumn : changed conditional boundary → NO_COVERAGE
2. shiftCurrentColumn : Replaced integer addition with subtraction → NO_COVERAGE
3. shiftCurrentColumn : negated conditional → NO_COVERAGE
        if (currentColumn + 1 < columnDefs.size()) {
489 1 1. shiftCurrentColumn : Replaced integer addition with subtraction → NO_COVERAGE
            currentColumn++;
490 1 1. shiftCurrentColumn : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE
            return true;
491
        }
492 1 1. shiftCurrentColumn : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE
        return false;
493
    }
494
    
495
    /**
496
     * Sets the direction of the columns.
497
     * @param direction true = right2left; false = left2right
498
     */
499
    public void setColumnsRightToLeft(boolean direction) {
500
        columnsRightToLeft = direction;
501
    }
502
    
503
    /** Sets the ratio between the extra word spacing and the extra character spacing
504
     * when the text is fully justified.
505
     * Extra word spacing will grow <CODE>spaceCharRatio</CODE> times more than extra character spacing.
506
     * If the ratio is <CODE>PdfWriter.NO_SPACE_CHAR_RATIO</CODE> then the extra character spacing
507
     * will be zero.
508
     * @param spaceCharRatio the ratio between the extra word spacing and the extra character spacing
509
     */
510
    public void setSpaceCharRatio(float spaceCharRatio) {
511
        columnText.setSpaceCharRatio(spaceCharRatio);
512
    }
513
514
    /** Sets the run direction. 
515
     * @param runDirection the run direction
516
     */    
517
    public void setRunDirection(int runDirection) {
518
        columnText.setRunDirection(runDirection);
519
    }
520
    
521
    /** Sets the arabic shaping options. The option can be AR_NOVOWEL,
522
     * AR_COMPOSEDTASHKEEL and AR_LIG.
523
     * @param arabicOptions the arabic shaping options
524
     */
525
    public void setArabicOptions(int arabicOptions) {
526
        columnText.setArabicOptions(arabicOptions);
527
    }
528
    
529
    /** Sets the default alignment
530
     * @param alignment the default alignment
531
     */
532
    public void setAlignment(int alignment) {
533
        columnText.setAlignment(alignment);
534
    }
535
    
536
    /**
537
     * Inner class used to define a column
538
     */
539
    private class ColumnDef {
540
        private float[] left;
541
        private float[] right;
542
543
        ColumnDef(float[] newLeft, float[] newRight) {
544
            left = newLeft;
545
            right = newRight;
546
        }
547
548
        ColumnDef(float leftPosition, float rightPosition) {
549
            left = new float[4];
550
            left[0] = leftPosition; // x1
551
            left[1] = top;          // y1
552
            left[2] = leftPosition; // x2
553 2 1. : negated conditional → NO_COVERAGE
2. : negated conditional → NO_COVERAGE
            if (desiredHeight == AUTOMATIC || top == AUTOMATIC) {
554
                left[3] = AUTOMATIC;
555
            } else {
556 1 1. : Replaced float subtraction with addition → NO_COVERAGE
                left[3] = top - desiredHeight;
557
            }
558
559
            right = new float[4];
560
            right[0] = rightPosition; // x1
561
            right[1] = top;           // y1
562
            right[2] = rightPosition; // x2
563 2 1. : negated conditional → NO_COVERAGE
2. : negated conditional → NO_COVERAGE
            if (desiredHeight == AUTOMATIC || top == AUTOMATIC) {
564
                right[3] = AUTOMATIC;
565
            } else {
566 1 1. : Replaced float subtraction with addition → NO_COVERAGE
                right[3] = top - desiredHeight;
567
            }
568
        }
569
570
        /**
571
         * Resolves the positions for the specified side of the column
572
         * into real numbers once the top of the column is known.
573
         *
574
         * @param side either <CODE>Rectangle.LEFT</CODE>
575
         *             or <CODE>Rectangle.RIGHT</CODE>
576
         * @return the array of floats for the side
577
         */
578
        float[] resolvePositions(int side) {
579 1 1. resolvePositions : negated conditional → NO_COVERAGE
            if (side == Rectangle.LEFT) {
580 1 1. resolvePositions : mutated return of Object value for com/lowagie/text/pdf/MultiColumnText$ColumnDef::resolvePositions to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
                return resolvePositions(left);
581
            } else {
582 1 1. resolvePositions : mutated return of Object value for com/lowagie/text/pdf/MultiColumnText$ColumnDef::resolvePositions to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
                return resolvePositions(right);
583
            }
584
        }
585
586
        private float[] resolvePositions(float[] positions) {
587 1 1. resolvePositions : negated conditional → NO_COVERAGE
            if (!isSimple()) {
588
                positions[1] = top;
589 1 1. resolvePositions : mutated return of Object value for com/lowagie/text/pdf/MultiColumnText$ColumnDef::resolvePositions to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
                return positions;
590
            }
591 1 1. resolvePositions : negated conditional → NO_COVERAGE
            if (top == AUTOMATIC) {
592
                // this is bad - must be programmer error
593
                throw new RuntimeException("resolvePositions called with top=AUTOMATIC (-1).  " +
594
                        "Top position must be set befure lines can be resolved");
595
            }
596
            positions[1] = top;
597
            positions[3] = getColumnBottom();
598 1 1. resolvePositions : mutated return of Object value for com/lowagie/text/pdf/MultiColumnText$ColumnDef::resolvePositions to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
            return positions;
599
        }
600
601
        /**
602
         * Checks if column definition is a simple rectangle
603
         * @return true if it is a simple column 
604
         */
605
        private boolean isSimple() {
606 5 1. isSimple : negated conditional → NO_COVERAGE
2. isSimple : negated conditional → NO_COVERAGE
3. isSimple : negated conditional → NO_COVERAGE
4. isSimple : negated conditional → NO_COVERAGE
5. isSimple : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE
            return (left.length == 4 && right.length == 4) && (left[0] == left[2] && right[0] == right[2]);
607
        }
608
609
    }
610
}

Mutations

194

1.1
Location : addColumn
Killed by : none
negated conditional → NO_COVERAGE

221

1.1
Location : addRegularColumns
Killed by : none
Replaced float subtraction with addition → NO_COVERAGE

222

1.1
Location : addRegularColumns
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

2.2
Location : addRegularColumns
Killed by : none
Replaced float multiplication with division → NO_COVERAGE

3.3
Location : addRegularColumns
Killed by : none
Replaced float subtraction with addition → NO_COVERAGE

4.4
Location : addRegularColumns
Killed by : none
Replaced float division with multiplication → NO_COVERAGE

223

1.1
Location : addRegularColumns
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : addRegularColumns
Killed by : none
Changed increment from 1 to -1 → NO_COVERAGE

3.3
Location : addRegularColumns
Killed by : none
negated conditional → NO_COVERAGE

224

1.1
Location : addRegularColumns
Killed by : none
Replaced float addition with subtraction → NO_COVERAGE

2.2
Location : addRegularColumns
Killed by : none
removed call to com/lowagie/text/pdf/MultiColumnText::addSimpleColumn → NO_COVERAGE

225

1.1
Location : addRegularColumns
Killed by : none
Replaced float addition with subtraction → NO_COVERAGE

2.2
Location : addRegularColumns
Killed by : none
Replaced float addition with subtraction → NO_COVERAGE

260

1.1
Location : addElement
Killed by : none
negated conditional → NO_COVERAGE

261

1.1
Location : addElement
Killed by : none
removed call to com/lowagie/text/pdf/ColumnText::addElement → NO_COVERAGE

262

1.1
Location : addElement
Killed by : none
negated conditional → NO_COVERAGE

263

1.1
Location : addElement
Killed by : none
removed call to com/lowagie/text/pdf/ColumnText::addText → NO_COVERAGE

264

1.1
Location : addElement
Killed by : none
negated conditional → NO_COVERAGE

265

1.1
Location : addElement
Killed by : none
removed call to com/lowagie/text/pdf/ColumnText::addText → NO_COVERAGE

283

1.1
Location : write
Killed by : none
removed call to com/lowagie/text/pdf/ColumnText::setCanvas → NO_COVERAGE

284

1.1
Location : write
Killed by : none
negated conditional → NO_COVERAGE

291

1.1
Location : write
Killed by : none
negated conditional → NO_COVERAGE

292

1.1
Location : write
Killed by : none
negated conditional → NO_COVERAGE

295

1.1
Location : write
Killed by : none
negated conditional → NO_COVERAGE

299

1.1
Location : write
Killed by : none
removed call to com/lowagie/text/pdf/ColumnText::setYLine → NO_COVERAGE

303

1.1
Location : write
Killed by : none
Replaced integer modulus with multiplication → NO_COVERAGE

2.2
Location : write
Killed by : none
negated conditional → NO_COVERAGE

3.3
Location : write
Killed by : none
negated conditional → NO_COVERAGE

304

1.1
Location : write
Killed by : none
Replaced float subtraction with addition → NO_COVERAGE

307

1.1
Location : write
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : write
Killed by : none
negated conditional → NO_COVERAGE

308

1.1
Location : write
Killed by : none
Replaced float subtraction with addition → NO_COVERAGE

310

1.1
Location : write
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : write
Killed by : none
negated conditional → NO_COVERAGE

311

1.1
Location : write
Killed by : none
Replaced float subtraction with addition → NO_COVERAGE

317

1.1
Location : write
Killed by : none
negated conditional → NO_COVERAGE

318

1.1
Location : write
Killed by : none
removed call to com/lowagie/text/pdf/ColumnText::setSimpleColumn → NO_COVERAGE

320

1.1
Location : write
Killed by : none
removed call to com/lowagie/text/pdf/ColumnText::setColumns → NO_COVERAGE

324

1.1
Location : write
Killed by : none
Replaced bitwise AND with OR → NO_COVERAGE

2.2
Location : write
Killed by : none
negated conditional → NO_COVERAGE

327

1.1
Location : write
Killed by : none
negated conditional → NO_COVERAGE

330

1.1
Location : write
Killed by : none
Replaced float addition with subtraction → NO_COVERAGE

331

1.1
Location : write
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : write
Killed by : none
negated conditional → NO_COVERAGE

3.3
Location : write
Killed by : none
negated conditional → NO_COVERAGE

336

1.1
Location : write
Killed by : none
removed call to com/lowagie/text/pdf/MultiColumnText::newPage → NO_COVERAGE

342

1.1
Location : write
Killed by : none
removed call to com/lowagie/text/DocumentException::printStackTrace → NO_COVERAGE

345

1.1
Location : write
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location : write
Killed by : none
negated conditional → NO_COVERAGE

346

1.1
Location : write
Killed by : none
Replaced float subtraction with addition → NO_COVERAGE

348

1.1
Location : write
Killed by : none
replaced return of float value with -(x + 1) for com/lowagie/text/pdf/MultiColumnText::write → NO_COVERAGE

352

1.1
Location : newPage
Killed by : none
removed call to com/lowagie/text/pdf/MultiColumnText::resetCurrentColumn → NO_COVERAGE

353

1.1
Location : newPage
Killed by : none
negated conditional → NO_COVERAGE

360

1.1
Location : newPage
Killed by : none
negated conditional → NO_COVERAGE

375

1.1
Location : getHeight
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : getHeight
Killed by : none
negated conditional → NO_COVERAGE

376

1.1
Location : getHeight
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

377

1.1
Location : getHeight
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

379

1.1
Location : getHeight
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : getHeight
Killed by : none
negated conditional → NO_COVERAGE

380

1.1
Location : getHeight
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

381

1.1
Location : getHeight
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

383

1.1
Location : getHeight
Killed by : none
Replaced float subtraction with addition → NO_COVERAGE

2.2
Location : getHeight
Killed by : none
replaced return of float value with -(x + 1) for com/lowagie/text/pdf/MultiColumnText::getHeight → NO_COVERAGE

396

1.1
Location : process
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

398

1.1
Location : process
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

445

1.1
Location : getColumnBottom
Killed by : none
negated conditional → NO_COVERAGE

446

1.1
Location : getColumnBottom
Killed by : none
replaced return of float value with -(x + 1) for com/lowagie/text/pdf/MultiColumnText::getColumnBottom → NO_COVERAGE

448

1.1
Location : getColumnBottom
Killed by : none
Replaced float subtraction with addition → NO_COVERAGE

2.2
Location : getColumnBottom
Killed by : none
Replaced float subtraction with addition → NO_COVERAGE

3.3
Location : getColumnBottom
Killed by : none
replaced return of float value with -(x + 1) for com/lowagie/text/pdf/MultiColumnText::getColumnBottom → NO_COVERAGE

458

1.1
Location : nextColumn
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

2.2
Location : nextColumn
Killed by : none
Replaced integer modulus with multiplication → NO_COVERAGE

460

1.1
Location : nextColumn
Killed by : none
negated conditional → NO_COVERAGE

461

1.1
Location : nextColumn
Killed by : none
removed call to com/lowagie/text/pdf/MultiColumnText::newPage → NO_COVERAGE

470

1.1
Location : getCurrentColumn
Killed by : none
negated conditional → NO_COVERAGE

471

1.1
Location : getCurrentColumn
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

2.2
Location : getCurrentColumn
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

3.3
Location : getCurrentColumn
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

473

1.1
Location : getCurrentColumn
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

488

1.1
Location : shiftCurrentColumn
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : shiftCurrentColumn
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

3.3
Location : shiftCurrentColumn
Killed by : none
negated conditional → NO_COVERAGE

489

1.1
Location : shiftCurrentColumn
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

490

1.1
Location : shiftCurrentColumn
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

492

1.1
Location : shiftCurrentColumn
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

553

1.1
Location :
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location :
Killed by : none
negated conditional → NO_COVERAGE

556

1.1
Location :
Killed by : none
Replaced float subtraction with addition → NO_COVERAGE

563

1.1
Location :
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location :
Killed by : none
negated conditional → NO_COVERAGE

566

1.1
Location :
Killed by : none
Replaced float subtraction with addition → NO_COVERAGE

579

1.1
Location : resolvePositions
Killed by : none
negated conditional → NO_COVERAGE

580

1.1
Location : resolvePositions
Killed by : none
mutated return of Object value for com/lowagie/text/pdf/MultiColumnText$ColumnDef::resolvePositions to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

582

1.1
Location : resolvePositions
Killed by : none
mutated return of Object value for com/lowagie/text/pdf/MultiColumnText$ColumnDef::resolvePositions to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

587

1.1
Location : resolvePositions
Killed by : none
negated conditional → NO_COVERAGE

589

1.1
Location : resolvePositions
Killed by : none
mutated return of Object value for com/lowagie/text/pdf/MultiColumnText$ColumnDef::resolvePositions to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

591

1.1
Location : resolvePositions
Killed by : none
negated conditional → NO_COVERAGE

598

1.1
Location : resolvePositions
Killed by : none
mutated return of Object value for com/lowagie/text/pdf/MultiColumnText$ColumnDef::resolvePositions to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

606

1.1
Location : isSimple
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location : isSimple
Killed by : none
negated conditional → NO_COVERAGE

3.3
Location : isSimple
Killed by : none
negated conditional → NO_COVERAGE

4.4
Location : isSimple
Killed by : none
negated conditional → NO_COVERAGE

5.5
Location : isSimple
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.4.2