~ubuntu-branches/ubuntu/raring/libitext-java/raring-proposed

« back to all changes in this revision

Viewing changes to com/lowagie/text/pdf/PdfLine.java

  • Committer: Bazaar Package Importer
  • Author(s): Adriaan Peeters
  • Date: 2008-11-23 12:26:51 UTC
  • mfrom: (5.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20081123122651-ab7juwjz41q1123k
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * $Id: PdfLine.java,v 1.66 2006/01/18 20:35:48 psoares33 Exp $
3
 
 * $Name:  $
4
 
 *
5
 
 * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
6
 
 *
7
 
 * The contents of this file are subject to the Mozilla Public License Version 1.1
8
 
 * (the "License"); you may not use this file except in compliance with the License.
9
 
 * You may obtain a copy of the License at http://www.mozilla.org/MPL/
10
 
 *
11
 
 * Software distributed under the License is distributed on an "AS IS" basis,
12
 
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13
 
 * for the specific language governing rights and limitations under the License.
14
 
 *
15
 
 * The Original Code is 'iText, a free JAVA-PDF library'.
16
 
 *
17
 
 * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
18
 
 * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
19
 
 * All Rights Reserved.
20
 
 * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
21
 
 * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
22
 
 *
23
 
 * Contributor(s): all the names of the contributors are added in the source code
24
 
 * where applicable.
25
 
 *
26
 
 * Alternatively, the contents of this file may be used under the terms of the
27
 
 * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
28
 
 * provisions of LGPL are applicable instead of those above.  If you wish to
29
 
 * allow use of your version of this file only under the terms of the LGPL
30
 
 * License and not to allow others to use your version of this file under
31
 
 * the MPL, indicate your decision by deleting the provisions above and
32
 
 * replace them with the notice and other provisions required by the LGPL.
33
 
 * If you do not delete the provisions above, a recipient may use your version
34
 
 * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
35
 
 *
36
 
 * This library is free software; you can redistribute it and/or modify it
37
 
 * under the terms of the MPL as stated above or under the terms of the GNU
38
 
 * Library General Public License as published by the Free Software Foundation;
39
 
 * either version 2 of the License, or any later version.
40
 
 *
41
 
 * This library is distributed in the hope that it will be useful, but WITHOUT
42
 
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
43
 
 * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
44
 
 * details.
45
 
 *
46
 
 * If you didn't download this code from the following link, you should check if
47
 
 * you aren't using an obsolete version:
48
 
 * http://www.lowagie.com/iText/
49
 
 */
50
 
 
51
 
package com.lowagie.text.pdf;
52
 
 
53
 
import java.util.ArrayList;
54
 
import java.util.Iterator;
55
 
 
56
 
import com.lowagie.text.Element;
57
 
import com.lowagie.text.ListItem;
58
 
import com.lowagie.text.Chunk;
59
 
 
60
 
/**
61
 
 * <CODE>PdfLine</CODE> defines an array with <CODE>PdfChunk</CODE>-objects
62
 
 * that fit into 1 line.
63
 
 */
64
 
 
65
 
public class PdfLine {
66
 
    
67
 
    // membervariables
68
 
    
69
 
    /** The arraylist containing the chunks. */
70
 
    protected ArrayList line;
71
 
    
72
 
    /** The left indentation of the line. */
73
 
    protected float left;
74
 
    
75
 
    /** The width of the line. */
76
 
    protected float width;
77
 
    
78
 
    /** The alignment of the line. */
79
 
    protected int alignment;
80
 
    
81
 
    /** The heigth of the line. */
82
 
    protected float height;
83
 
    
84
 
    /** The listsymbol (if necessary). */
85
 
    protected Chunk listSymbol = null;
86
 
    
87
 
    /** The listsymbol (if necessary). */
88
 
    protected float symbolIndent;
89
 
    
90
 
    /** <CODE>true</CODE> if the chunk splitting was caused by a newline. */
91
 
    protected boolean newlineSplit = false;
92
 
    
93
 
    /** The original width. */
94
 
    protected float originalWidth;
95
 
    
96
 
    protected boolean isRTL = false;
97
 
    
98
 
    // constructors
99
 
    
100
 
    /**
101
 
     * Constructs a new <CODE>PdfLine</CODE>-object.
102
 
     *
103
 
     * @param   left            the limit of the line at the left
104
 
     * @param   right           the limit of the line at the right
105
 
     * @param   alignment       the alignment of the line
106
 
     * @param   height          the height of the line
107
 
     */
108
 
    
109
 
    PdfLine(float left, float right, int alignment, float height) {
110
 
        this.left = left;
111
 
        this.width = right - left;
112
 
        this.originalWidth = this.width;
113
 
        this.alignment = alignment;
114
 
        this.height = height;
115
 
        this.line = new ArrayList();
116
 
    }
117
 
    
118
 
    PdfLine(float left, float remainingWidth, int alignment, boolean newlineSplit, ArrayList line, boolean isRTL) {
119
 
        this.left = left;
120
 
        this.width = remainingWidth;
121
 
        this.alignment = alignment;
122
 
        this.line = line;
123
 
        this.newlineSplit = newlineSplit;
124
 
        this.isRTL = isRTL;
125
 
    }
126
 
    
127
 
    // methods
128
 
    
129
 
    /**
130
 
     * Adds a <CODE>PdfChunk</CODE> to the <CODE>PdfLine</CODE>.
131
 
     *
132
 
     * @param           chunk           the <CODE>PdfChunk</CODE> to add
133
 
     * @return          <CODE>null</CODE> if the chunk could be added completely; if not
134
 
     *                          a <CODE>PdfChunk</CODE> containing the part of the chunk that could
135
 
     *                          not be added is returned
136
 
     */
137
 
    
138
 
    PdfChunk add(PdfChunk chunk) {
139
 
        // nothing happens if the chunk is null.
140
 
        if (chunk == null || chunk.toString().equals("")) {
141
 
            return null;
142
 
        }
143
 
        
144
 
        // we split the chunk to be added
145
 
        PdfChunk overflow = chunk.split(width);
146
 
        newlineSplit = (chunk.isNewlineSplit() || overflow == null);
147
 
        //        if (chunk.isNewlineSplit() && alignment == Element.ALIGN_JUSTIFIED)
148
 
        //            alignment = Element.ALIGN_LEFT;
149
 
        
150
 
        
151
 
        // if the length of the chunk > 0 we add it to the line
152
 
        if (chunk.length() > 0) {
153
 
            if (overflow != null)
154
 
                chunk.trimLastSpace();
155
 
            width -= chunk.width();
156
 
            line.add(chunk);
157
 
        }
158
 
        
159
 
        // if the length == 0 and there were no other chunks added to the line yet,
160
 
        // we risk to end up in an endless loop trying endlessly to add the same chunk
161
 
        else if (line.size() < 1) {
162
 
            chunk = overflow;
163
 
            overflow = chunk.truncate(width);
164
 
            width -= chunk.width();
165
 
            if (chunk.length() > 0) {
166
 
                line.add(chunk);
167
 
                return overflow;
168
 
            }
169
 
            // if the chunck couldn't even be truncated, we add everything, so be it
170
 
            else {
171
 
                if (overflow != null)
172
 
                    line.add(overflow);
173
 
                return null;
174
 
            }
175
 
        }
176
 
        else {
177
 
            width += ((PdfChunk)(line.get(line.size() - 1))).trimLastSpace();
178
 
        }
179
 
        return overflow;
180
 
    }
181
 
    
182
 
    // methods to retrieve information
183
 
    
184
 
    /**
185
 
     * Returns the number of chunks in the line.
186
 
     *
187
 
     * @return  a value
188
 
     */
189
 
    
190
 
    public int size() {
191
 
        return line.size();
192
 
    }
193
 
    
194
 
    /**
195
 
     * Returns an iterator of <CODE>PdfChunk</CODE>s.
196
 
     *
197
 
     * @return  an <CODE>Iterator</CODE>
198
 
     */
199
 
    
200
 
    public Iterator iterator() {
201
 
        return line.iterator();
202
 
    }
203
 
    
204
 
    /**
205
 
     * Returns the height of the line.
206
 
     *
207
 
     * @return  a value
208
 
     */
209
 
    
210
 
    float height() {
211
 
        return height;
212
 
    }
213
 
    
214
 
    /**
215
 
     * Returns the left indentation of the line taking the alignment of the line into account.
216
 
     *
217
 
     * @return  a value
218
 
     */
219
 
    
220
 
    float indentLeft() {
221
 
        if (isRTL) {
222
 
            switch (alignment) {
223
 
                case Element.ALIGN_LEFT:
224
 
                    return left + width;
225
 
                case Element.ALIGN_CENTER:
226
 
                    return left + (width / 2f);
227
 
                default:
228
 
                    return left;
229
 
            }
230
 
        }
231
 
        else {
232
 
            switch (alignment) {
233
 
                case Element.ALIGN_RIGHT:
234
 
                    return left + width;
235
 
                case Element.ALIGN_CENTER:
236
 
                    return left + (width / 2f);
237
 
                default:
238
 
                    return left;
239
 
            }
240
 
        }
241
 
    }
242
 
    
243
 
    /**
244
 
     * Checks if this line has to be justified.
245
 
     *
246
 
     * @return  <CODE>true</CODE> if the alignment equals <VAR>ALIGN_JUSTIFIED</VAR> and there is some width left.
247
 
     */
248
 
    
249
 
    public boolean hasToBeJustified() {
250
 
        return ((alignment == Element.ALIGN_JUSTIFIED || alignment == Element.ALIGN_JUSTIFIED_ALL) && width != 0);
251
 
    }
252
 
    
253
 
    /**
254
 
     * Resets the alignment of this line.
255
 
     * <P>
256
 
     * The alignment of the last line of for instance a <CODE>Paragraph</CODE>
257
 
     * that has to be justified, has to be reset to <VAR>ALIGN_LEFT</VAR>.
258
 
     */
259
 
    
260
 
    public void resetAlignment() {
261
 
        if (alignment == Element.ALIGN_JUSTIFIED) {
262
 
            alignment = Element.ALIGN_LEFT;
263
 
        }
264
 
    }
265
 
    
266
 
    /**
267
 
     * Returns the width that is left, after a maximum of characters is added to the line.
268
 
     *
269
 
     * @return  a value
270
 
     */
271
 
    
272
 
    float widthLeft() {
273
 
        return width;
274
 
    }
275
 
    
276
 
    /**
277
 
     * Returns the number of space-characters in this line.
278
 
     *
279
 
     * @return  a value
280
 
     */
281
 
    
282
 
    int numberOfSpaces() {
283
 
        String string = toString();
284
 
        int length = string.length();
285
 
        int numberOfSpaces = 0;
286
 
        for (int i = 0; i < length; i++) {
287
 
            if (string.charAt(i) == ' ') {
288
 
                numberOfSpaces++;
289
 
            }
290
 
        }
291
 
        return numberOfSpaces;
292
 
    }
293
 
    
294
 
    /**
295
 
     * Sets the listsymbol of this line.
296
 
     * <P>
297
 
     * This is only necessary for the first line of a <CODE>ListItem</CODE>.
298
 
     *
299
 
     * @param listItem the list symbol
300
 
     */
301
 
    
302
 
    public void setListItem(ListItem listItem) {
303
 
        this.listSymbol = listItem.listSymbol();
304
 
        this.symbolIndent = listItem.indentationLeft();
305
 
    }
306
 
    
307
 
    /**
308
 
     * Returns the listsymbol of this line.
309
 
     *
310
 
     * @return  a <CODE>PdfChunk</CODE> if the line has a listsymbol; <CODE>null</CODE> otherwise
311
 
     */
312
 
    
313
 
    public Chunk listSymbol() {
314
 
        return listSymbol;
315
 
    }
316
 
    
317
 
    /**
318
 
     * Return the indentation needed to show the listsymbol.
319
 
     *
320
 
     * @return  a value
321
 
     */
322
 
    
323
 
    public float listIndent() {
324
 
        return symbolIndent;
325
 
    }
326
 
    
327
 
    /**
328
 
     * Get the string representation of what is in this line.
329
 
     *
330
 
     * @return  a <CODE>String</CODE>
331
 
     */
332
 
    
333
 
    public String toString() {
334
 
        StringBuffer tmp = new StringBuffer();
335
 
        for (Iterator i = line.iterator(); i.hasNext(); ) {
336
 
            tmp.append(((PdfChunk) i.next()).toString());
337
 
        }
338
 
        return tmp.toString();
339
 
    }
340
 
    
341
 
    /**
342
 
     * Checks if a newline caused the line split.
343
 
     * @return <CODE>true</CODE> if a newline caused the line split
344
 
     */
345
 
    public boolean isNewlineSplit() {
346
 
        return newlineSplit && (alignment != Element.ALIGN_JUSTIFIED_ALL);
347
 
    }
348
 
    
349
 
    /**
350
 
     * Gets the index of the last <CODE>PdfChunk</CODE> with metric attributes
351
 
     * @return the last <CODE>PdfChunk</CODE> with metric attributes
352
 
     */
353
 
    public int getLastStrokeChunk() {
354
 
        int lastIdx = line.size() - 1;
355
 
        for (; lastIdx >= 0; --lastIdx) {
356
 
            PdfChunk chunk = (PdfChunk)line.get(lastIdx);
357
 
            if (chunk.isStroked())
358
 
                break;
359
 
        }
360
 
        return lastIdx;
361
 
    }
362
 
    
363
 
    /**
364
 
     * Gets a <CODE>PdfChunk</CODE> by index.
365
 
     * @param idx the index
366
 
     * @return the <CODE>PdfChunk</CODE> or null if beyond the array
367
 
     */
368
 
    public PdfChunk getChunk(int idx) {
369
 
        if (idx < 0 || idx >= line.size())
370
 
            return null;
371
 
        return (PdfChunk)line.get(idx);
372
 
    }
373
 
    
374
 
    /**
375
 
     * Gets the original width of the line.
376
 
     * @return the original width of the line
377
 
     */
378
 
    public float getOriginalWidth() {
379
 
        return originalWidth;
380
 
    }
381
 
    
382
 
    /**
383
 
     * Gets the maximum size of all the fonts used in this line
384
 
     * including images (if there are images in the line and if
385
 
     * the leading has to be changed).
386
 
     * @return maximum size of all the fonts used in this line
387
 
     */
388
 
    float getMaxSize() {
389
 
        float maxSize = 0;
390
 
        for (int k = 0; k < line.size(); ++k) {
391
 
            PdfChunk chunk = (PdfChunk)line.get(k);
392
 
            if (!chunk.isImage() || !chunk.changeLeading()) {
393
 
                maxSize = Math.max(chunk.font().size(), maxSize);
394
 
            }
395
 
            else {
396
 
                maxSize = Math.max(chunk.getImage().scaledHeight() + chunk.getImageOffsetY() , maxSize);
397
 
            }
398
 
        }
399
 
        return maxSize;
400
 
    }
401
 
    
402
 
    /**
403
 
     * Gets the maximum size of all the fonts used in this line
404
 
     * including images.
405
 
     * @return maximum size of all the fonts used in this line
406
 
     */
407
 
    float getMaxSizeSimple() {
408
 
        float maxSize = 0;
409
 
        for (int k = 0; k < line.size(); ++k) {
410
 
            PdfChunk chunk = (PdfChunk)line.get(k);
411
 
            if (!chunk.isImage()) {
412
 
                maxSize = Math.max(chunk.font().size(), maxSize);
413
 
            }
414
 
            else {
415
 
                maxSize = Math.max(chunk.getImage().scaledHeight() + chunk.getImageOffsetY() , maxSize);
416
 
            }
417
 
        }
418
 
        return maxSize;
419
 
    }
420
 
    
421
 
    boolean isRTL() {
422
 
        return isRTL;
423
 
    }
424
 
    
425
 
    /**
426
 
     * Gets a width corrected with a charSpacing and wordSpacing.
427
 
     * @param charSpacing
428
 
     * @param wordSpacing
429
 
     * @return a corrected width
430
 
     */
431
 
    public float getWidthCorrected(float charSpacing, float wordSpacing) {
432
 
        float total = 0;
433
 
        for (int k = 0; k < line.size(); ++k) {
434
 
            PdfChunk ck = (PdfChunk)line.get(k);
435
 
            total += ck.getWidthCorrected(charSpacing, wordSpacing);
436
 
        }
437
 
        return total;
438
 
    }
439
 
    
440
 
/**
441
 
 * Gets the maximum size of the ascender for all the fonts used
442
 
 * in this line.
443
 
 * @return maximum size of all the ascenders used in this line
444
 
 */
445
 
   public float getAscender() {
446
 
       float ascender = 0;
447
 
       for (int k = 0; k < line.size(); ++k) {
448
 
           PdfChunk ck = (PdfChunk)line.get(k);
449
 
           if (ck.isImage())
450
 
               ascender = Math.max(ascender, ck.getImage().scaledHeight() + ck.getImageOffsetY());
451
 
           else {
452
 
               PdfFont font = ck.font();
453
 
               ascender = Math.max(ascender, font.getFont().getFontDescriptor(BaseFont.ASCENT, font.size()));
454
 
           }
455
 
       }
456
 
       return ascender;
457
 
   }
458
 
 
459
 
/**
460
 
 * Gets the biggest descender for all the fonts used 
461
 
 * in this line.  Note that this is a negative number.
462
 
 * @return maximum size of all the ascenders used in this line
463
 
 */
464
 
    public float getDescender() {
465
 
        float descender = 0;
466
 
        for (int k = 0; k < line.size(); ++k) {
467
 
            PdfChunk ck = (PdfChunk)line.get(k);
468
 
            if (ck.isImage())
469
 
                descender = Math.min(descender, ck.getImageOffsetY());
470
 
            else {
471
 
                PdfFont font = ck.font();
472
 
                descender = Math.min(descender, font.getFont().getFontDescriptor(BaseFont.DESCENT, font.size()));
473
 
            }
474
 
        }
475
 
        return descender;
476
 
    }
477
 
}
 
 
b'\\ No newline at end of file'