001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /* $Id: RtfText.java 426576 2006-07-28 15:44:37Z jeremias $ */
019:
020: /*
021: * This file is part of the RTF library of the FOP project, which was originally
022: * created by Bertrand Delacretaz <bdelacretaz@codeconsult.ch> and by other
023: * contributors to the jfor project (www.jfor.org), who agreed to donate jfor to
024: * the FOP project.
025: */
026:
027: package org.apache.fop.render.rtf.rtflib.rtfdoc;
028:
029: import java.io.IOException;
030: import java.io.Writer;
031:
032: /** Model of a text run (a piece of text with attributes) in an RTF document
033: * @author Bertrand Delacretaz bdelacretaz@codeconsult.ch
034: */
035:
036: public class RtfText extends RtfElement {
037: // char code for non-breakable space
038: private static final int CHAR_NBSP = 160;
039: private static final int CHAR_TAB = 137;
040: private static final int CHAR_NEW_LINE = 141;
041: /* these next two variables are used to encode bold formating in the
042: * raw xml text. Usefull when specific words or phrases are to be bolded
043: * but their placement and length change. Thus the bold formatting becomes
044: * part of the data. The same method can be used for implementing other types
045: * of raw text formatting.
046: */
047: private static final int CHAR_BOLD_START = 130;
048: private static final int CHAR_BOLD_END = 131;
049:
050: /** members */
051: private String text;
052: private final RtfAttributes attr;
053:
054: /** RtfText attributes: attribute names are RTF control word names to avoid
055: * additional mapping */
056: /** constant for bold */
057: public static final String ATTR_BOLD = "b";
058: /** constant for italic */
059: public static final String ATTR_ITALIC = "i";
060: /** constant for underline */
061: public static final String ATTR_UNDERLINE = "ul";
062: /** constant for underline */
063: public static final String ATTR_STRIKETHROUGH = "strike";
064: /** constant for font size */
065: public static final String ATTR_FONT_SIZE = "fs";
066: /** constant for font family */
067: public static final String ATTR_FONT_FAMILY = "f";
068: /** constant for font color */
069: public static final String ATTR_FONT_COLOR = "cf";
070: /** constant for background color */
071: public static final String ATTR_BACKGROUND_COLOR = "chcbpat"; // Added by Boris on 06/25//02
072: /** constant for superscript */
073: public static final String ATTR_SUPERSCRIPT = "super";
074: /** constant for subscript */
075: public static final String ATTR_SUBSCRIPT = "sub";
076:
077: /** RtfText attributes: paragraph shading attributes */
078: /** Constant for the shading of the paragraph */
079: public static final String SHADING = "shading";
080: /** Constant for the document's color tableshading of the paragraph */
081: public static final String SHADING_FRONT_COLOR = "cfpat";
082: /** Constant for the 100% shading of the paragraph */
083: public static final int FULL_SHADING = 10000;
084:
085: /** RtfText attributes: alignment attributes */
086: /** constant for align center */
087: public static final String ALIGN_CENTER = "qc";
088: /** constant for align left */
089: public static final String ALIGN_LEFT = "ql";
090: /** constant for align right */
091: public static final String ALIGN_RIGHT = "qr";
092: /** constant for align justified */
093: public static final String ALIGN_JUSTIFIED = "qj";
094: /** constant for align distributed */
095: public static final String ALIGN_DISTRIBUTED = "qd";
096:
097: /** RtfText attributes: border attributes */
098: //added by Chris Scott
099: /** constant for bottom single border */
100: public static final String BDR_BOTTOM_SINGLE = "brdrb\\brsp40\\brdrs";
101: /** constant for bottom double border */
102: public static final String BDR_BOTTOM_DOUBLE = "brdrb\\brsp40\\brdrdb";
103: /** constant for bottom embossed border */
104: public static final String BDR_BOTTOM_EMBOSS = "brdrb\\brsp40\\brdremboss";
105: /** constant for bottom dotted border */
106: public static final String BDR_BOTTOM_DOTTED = "brdrb\\brsp40\\brdrdot";
107: /** constant for bottom dashed border */
108: public static final String BDR_BOTTOM_DASH = "brdrb\\brsp40\\brdrdash";
109:
110: /** RtfText attributes: fields */
111: //must be carefull of group markings and star control
112: //ie page field:
113: // "{\field {\*\fldinst {PAGE}} {\fldrslt}}"
114: /** constant for field */
115: public static final String RTF_FIELD = "field";
116: /** constant for field page */
117: public static final String RTF_FIELD_PAGE = "fldinst { PAGE }";
118: /** constant for field result */
119: public static final String RTF_FIELD_RESULT = "fldrslt";
120:
121: /**RtfText attributes: indentation attributes */
122: //added by Chris Scott
123: /** constant for left indent body */
124: public static final String LEFT_INDENT_BODY = "li";
125: /** constant for left indent first */
126: public static final String LEFT_INDENT_FIRST = "fi-";
127: /** constant for right indent body */
128: public static final String RIGHT_INDENT_BODY = "ri";
129:
130: /** constant for center tab */
131: public static final String TAB_CENTER = "tqc\\tx";
132: /** constant for right tab */
133: public static final String TAB_RIGHT = "tqr\\tx";
134: /** constant for tab leader dots */
135: public static final String TAB_LEADER_DOTS = "tldot";
136: /** constant for tab leader hyphens */
137: public static final String TAB_LEADER_HYPHEN = "tlhyph";
138: /** constant for tab leader underscores */
139: public static final String TAB_LEADER_UNDER = "tlul";
140: /** constant for tab leader thick */
141: public static final String TAB_LEADER_THICK = "tlth";
142: /** constant for tab leader equals */
143: public static final String TAB_LEADER_EQUALS = "tleq";
144:
145: /** Space before/after a paragraph */
146: //these lines were added by Boris Pouderous
147: public static final String SPACE_BEFORE = "sb";
148: /** Space after a paragraph */
149: public static final String SPACE_AFTER = "sa";
150:
151: /** RtfText attributes: this must contain all allignment attributes names */
152: public static final String[] ALIGNMENT = new String[] {
153: ALIGN_CENTER, ALIGN_LEFT, ALIGN_RIGHT, ALIGN_JUSTIFIED,
154: ALIGN_DISTRIBUTED };
155:
156: /** RtfText attributes:: this must contain all border attribute names*/
157: //this line added by Chris Scott, Westinghouse
158: public static final String[] BORDER = new String[] {
159: BDR_BOTTOM_SINGLE, BDR_BOTTOM_DOUBLE, BDR_BOTTOM_EMBOSS,
160: BDR_BOTTOM_DOTTED, BDR_BOTTOM_DASH };
161:
162: /** String array of indent constants */
163: public static final String[] INDENT = new String[] {
164: LEFT_INDENT_BODY, LEFT_INDENT_FIRST };
165:
166: /** String array of tab constants */
167: public static final String[] TABS = new String[] { TAB_CENTER,
168: TAB_RIGHT, TAB_LEADER_DOTS, TAB_LEADER_HYPHEN,
169: TAB_LEADER_UNDER, TAB_LEADER_THICK, TAB_LEADER_EQUALS };
170:
171: /** RtfText attributes: this must contain all attribute names */
172: public static final String[] ATTR_NAMES = { ATTR_BOLD, ATTR_ITALIC,
173: ATTR_UNDERLINE, ATTR_FONT_SIZE, ATTR_FONT_FAMILY,
174: ATTR_FONT_COLOR, ATTR_BACKGROUND_COLOR };
175:
176: /** Create an RtfText in given IRtfTextContainer.
177: * @param str optional initial text content
178: */
179: RtfText(IRtfTextContainer parent, Writer w, String str,
180: RtfAttributes attr) throws IOException {
181: super ((RtfContainer) parent, w);
182: this .text = str;
183: this .attr = attr;
184: }
185:
186: /**
187: * Write our text to the RTF stream
188: * @throws IOException for I/O problems
189: */
190: public void writeRtfContent() throws IOException {
191: writeChars: {
192:
193: //these lines were added by Boris Pouderous
194: if (attr != null) {
195: writeAttributes(attr,
196: new String[] { RtfText.SPACE_BEFORE });
197: writeAttributes(attr,
198: new String[] { RtfText.SPACE_AFTER });
199: }
200:
201: if (isTab()) {
202: writeControlWord("tab");
203: } else if (isNewLine()) {
204: break writeChars;
205: } else if (isBold(true)) {
206: writeControlWord("b");
207: } else if (isBold(false)) {
208: writeControlWord("b0");
209: // TODO not optimal, consecutive RtfText with same attributes
210: // could be written without group marks
211: } else {
212: writeGroupMark(true);
213: if (attr != null && mustWriteAttributes()) {
214: writeAttributes(attr, RtfText.ATTR_NAMES);
215: }
216: RtfStringConverter.getInstance().writeRtfString(writer,
217: text);
218: writeGroupMark(false);
219: }
220: }
221: }
222:
223: /** true if our text attributes must be written */
224: private boolean mustWriteAttributes() {
225: return !isEmpty() && !isNbsp();
226: }
227:
228: /** IRtfTextContainer requirement:
229: * @return a copy of our attributes */
230: public RtfAttributes getTextContainerAttributes() {
231: if (attrib == null) {
232: return null;
233: }
234: return (RtfAttributes) this .attrib.clone();
235: }
236:
237: /** direct access to our text */
238: String getText() {
239: return text;
240: }
241:
242: /** direct access to our text */
243: void setText(String str) {
244: text = str;
245: }
246:
247: /**
248: * Checks whether the text is empty.
249: *
250: * @return true If m_text is null\n
251: * false m_text is set
252: */
253: public boolean isEmpty() {
254: return text == null || text.trim().length() == 0;
255: }
256:
257: /**
258: * True if text contains a single non-breaking space (#160).
259: * TODO make this more general and/or merge with isEmpty? -- what happen
260: * with empty paragraphs, if they will be removed, than NO, else ok
261: *
262: * @return true If m_text is character 160\n
263: * false m_text is not a nbsp
264: */
265: public boolean isNbsp() {
266: if (!isEmpty()) {
267: if (text.trim().length() == 1
268: && text.charAt(0) == CHAR_NBSP) {
269: return true;
270: }
271: }
272: return false;
273: }
274:
275: /**
276: * @return true if the text is a tab character
277: */
278: public boolean isTab() {
279: return (text.trim().length() == 1 && text.charAt(0) == CHAR_TAB);
280: }
281:
282: /**
283: * @return true if text is a newline character
284: */
285: public boolean isNewLine() {
286: return (text.trim().length() == 1 && text.charAt(0) == CHAR_NEW_LINE);
287: }
288:
289: /**
290: * @param isStart set to true if processing the start of the text (??)
291: * @return true if text is bold
292: */
293: public boolean isBold(boolean isStart) {
294: if (isStart) {
295: return (text.trim().length() == 1 && text.charAt(0) == CHAR_BOLD_START);
296: } else {
297: return (text.trim().length() == 1 && text.charAt(0) == CHAR_BOLD_END);
298: }
299: }
300:
301: /** @return the attributes of our text */
302: public RtfAttributes getTextAttributes() {
303: return attr;
304: }
305: }
|