001: /*
002: * ============================================================================
003: * GNU Lesser General Public License
004: * ============================================================================
005: *
006: * JasperReports - Free Java report-generating library.
007: * Copyright (C) 2001-2006 JasperSoft Corporation http://www.jaspersoft.com
008: *
009: * This library is free software; you can redistribute it and/or
010: * modify it under the terms of the GNU Lesser General Public
011: * License as published by the Free Software Foundation; either
012: * version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017: * Lesser General Public License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public
020: * License along with this library; if not, write to the Free Software
021: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
022: *
023: * JasperSoft Corporation
024: * 303 Second Street, Suite 450 North
025: * San Francisco, CA 94107
026: * http://www.jaspersoft.com
027: */
028: package net.sf.jasperreports.engine.util;
029:
030: import java.text.BreakIterator;
031: import java.text.CharacterIterator;
032: import java.text.StringCharacterIterator;
033:
034: import net.sf.jasperreports.engine.JRRuntimeException;
035:
036: import com.lowagie.text.SplitCharacter;
037: import com.lowagie.text.pdf.PdfChunk;
038:
039: /**
040: * Implementation of {@link com.lowagie.text.SplitCharacter SplitCharacter} that
041: * uses the same logic as AWT to break texts into lines.
042: *
043: * @author Lucian Chirita (lucianc@users.sourceforge.net)
044: * @version $Id: BreakIteratorSplitCharacter.java 1571 2007-01-29 13:41:53Z lucianc $
045: *
046: * @see net.sf.jasperreports.engine.export.JRPdfExporterParameter#FORCE_LINEBREAK_POLICY
047: * @see net.sf.jasperreports.engine.util.JRProperties#PDF_FORCE_LINEBREAK_POLICY
048: */
049: public class BreakIteratorSplitCharacter implements SplitCharacter {
050:
051: private char[] chars;
052: private int start, end;
053: private boolean[] boundary;
054: private int lastBoundary;
055: private final BreakIterator breakIter;
056:
057: public BreakIteratorSplitCharacter() {
058: this (BreakIterator.getLineInstance());
059: }
060:
061: public BreakIteratorSplitCharacter(BreakIterator breakIter) {
062: this .breakIter = breakIter;
063: }
064:
065: public boolean isSplitCharacter(int startIdx, int current,
066: int endIdx, char[] cc, PdfChunk[] ck) {
067: ++current;
068: if (current == endIdx) {
069: return false;
070: }
071:
072: if (!(chars == cc && this .start == startIdx && this .end == endIdx)) {
073: chars = cc;
074: this .start = startIdx;
075: this .end = endIdx;
076:
077: breakIter.setText(new ArrayCharIterator(cc, startIdx,
078: endIdx));
079:
080: boundary = new boolean[endIdx - startIdx + 1];
081:
082: lastBoundary = breakIter.first();
083: if (lastBoundary != BreakIterator.DONE) {
084: boundary[lastBoundary - startIdx] = true;
085: }
086: }
087:
088: while (current > lastBoundary) {
089: lastBoundary = breakIter.next();
090:
091: if (lastBoundary == BreakIterator.DONE) {
092: lastBoundary = Integer.MAX_VALUE;
093: } else {
094: boundary[lastBoundary - startIdx] = true;
095: }
096: }
097:
098: return boundary[current - startIdx];
099: }
100:
101: protected static class ArrayCharIterator implements
102: CharacterIterator {
103:
104: private char[] chars;
105: private int start;
106: private int end;
107: private int curr;
108:
109: public ArrayCharIterator(char[] chars, int start, int end) {
110: this .chars = chars;
111: this .start = start;
112: this .end = end;
113: }
114:
115: public char first() {
116: curr = start;
117: return current();
118: }
119:
120: public char last() {
121: if (end == start) {
122: curr = end;
123: } else {
124: curr = end - 1;
125: }
126: return current();
127: }
128:
129: public char setIndex(int position) {
130: if (position < start || position > end) {
131: throw new JRRuntimeException("Invalid index "
132: + position + " (start = " + start + ", end = "
133: + end + ")");
134: }
135: curr = position;
136: return current();
137: }
138:
139: public char current() {
140: if (curr < start || curr >= end) {
141: return DONE;
142: }
143: return chars[curr];
144: }
145:
146: public char next() {
147: if (curr >= end - 1) {
148: curr = end;
149: return DONE;
150: }
151: curr++;
152: return chars[curr];
153: }
154:
155: public char previous() {
156: if (curr <= start) {
157: return DONE;
158: }
159: curr--;
160: return chars[curr];
161: }
162:
163: public int getBeginIndex() {
164: return start;
165: }
166:
167: public int getEndIndex() {
168: return end;
169: }
170:
171: public int getIndex() {
172: return curr;
173: }
174:
175: public Object clone() {
176: try {
177: StringCharacterIterator other = (StringCharacterIterator) super
178: .clone();
179: return other;
180: } catch (CloneNotSupportedException e) {
181: throw new InternalError();
182: }
183: }
184: }
185:
186: }
|