1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 /* $Id: RtfText.java 1822095 2018-01-24 11:53:32Z ssteiner $ */ 19 20 package org.apache.fop.render.rtf.rtflib.rtfdoc; 21 22 /* 23 * This file is part of the RTF library of the FOP project, which was originally 24 * created by Bertrand Delacretaz bdelacretaz@codeconsult.ch and by other 25 * contributors to the jfor project (www.jfor.org), who agreed to donate jfor to 26 * the FOP project. 27 */ 28 29 import java.io.IOException; 30 import java.io.Writer; 31 32 import org.apache.fop.apps.FOPException; 33 34 /** 35 * <p>Model of a text run (a piece of text with attributes) in an RTF document.</p> 36 * 37 * <p>This work was authored by Bertrand Delacretaz (bdelacretaz@codeconsult.ch).</p> 38 */ 39 40 public class RtfText extends RtfElement { 41 // char code for non-breakable space 42 private static final int CHAR_NBSP = 160; 43 private static final int CHAR_TAB = 137; 44 private static final int CHAR_NEW_LINE = 141; 45 /* these next two variables are used to encode bold formating in the 46 * raw xml text. Usefull when specific words or phrases are to be bolded 47 * but their placement and length change. Thus the bold formatting becomes 48 * part of the data. The same method can be used for implementing other types 49 * of raw text formatting. 50 */ 51 private static final int CHAR_BOLD_START = 130; 52 private static final int CHAR_BOLD_END = 131; 53 54 /** members */ 55 private String text; 56 private final RtfAttributes attr; 57 58 59 /** RtfText attributes: attribute names are RTF control word names to avoid 60 * additional mapping */ 61 /** constant for bold */ 62 public static final String ATTR_BOLD = "b"; 63 /** constant for italic */ 64 public static final String ATTR_ITALIC = "i"; 65 /** constant for underline */ 66 public static final String ATTR_UNDERLINE = "ul"; 67 /** constant for underline */ 68 public static final String ATTR_STRIKETHROUGH = "strike"; 69 /** constant for font size */ 70 public static final String ATTR_FONT_SIZE = "fs"; 71 /** constant for font family */ 72 public static final String ATTR_FONT_FAMILY = "f"; 73 /** constant for font color */ 74 public static final String ATTR_FONT_COLOR = "cf"; 75 /** constant for background color */ 76 public static final String ATTR_BACKGROUND_COLOR = "chcbpat"; // Added by Boris on 06/25//02 77 /** constant for superscript */ 78 public static final String ATTR_SUPERSCRIPT = "super"; 79 /** constant for subscript */ 80 public static final String ATTR_SUBSCRIPT = "sub"; 81 82 /** RtfText attributes: paragraph shading attributes */ 83 /** Constant for the shading of the paragraph */ 84 public static final String SHADING = "shading"; 85 /** Constant for the document's color tableshading of the paragraph */ 86 public static final String SHADING_FRONT_COLOR = "cfpat"; 87 /** Constant for the 100% shading of the paragraph */ 88 public static final int FULL_SHADING = 10000; 89 90 /** RtfText attributes: alignment attributes */ 91 /** constant for align center */ 92 public static final String ALIGN_CENTER = "qc"; 93 /** constant for align left */ 94 public static final String ALIGN_LEFT = "ql"; 95 /** constant for align right */ 96 public static final String ALIGN_RIGHT = "qr"; 97 /** constant for align justified */ 98 public static final String ALIGN_JUSTIFIED = "qj"; 99 /** constant for align distributed */ 100 public static final String ALIGN_DISTRIBUTED = "qd"; 101 102 /** RtfText attributes: border attributes */ 103 //added by Chris Scott 104 /** constant for bottom single border */ 105 public static final String BDR_BOTTOM_SINGLE = "brdrb\\brsp40\\brdrs"; 106 /** constant for bottom double border */ 107 public static final String BDR_BOTTOM_DOUBLE = "brdrb\\brsp40\\brdrdb"; 108 /** constant for bottom embossed border */ 109 public static final String BDR_BOTTOM_EMBOSS = "brdrb\\brsp40\\brdremboss"; 110 /** constant for bottom dotted border */ 111 public static final String BDR_BOTTOM_DOTTED = "brdrb\\brsp40\\brdrdot"; 112 /** constant for bottom dashed border */ 113 public static final String BDR_BOTTOM_DASH = "brdrb\\brsp40\\brdrdash"; 114 115 /** RtfText attributes: fields */ 116 //must be carefull of group markings and star control 117 //ie page field: 118 // "{\field {\*\fldinst {PAGE}} {\fldrslt}}" 119 /** constant for field */ 120 public static final String RTF_FIELD = "field"; 121 /** constant for field page */ 122 public static final String RTF_FIELD_PAGE = "fldinst { PAGE }"; 123 /** constant for field result */ 124 public static final String RTF_FIELD_RESULT = "fldrslt"; 125 126 /**RtfText attributes: indentation attributes */ 127 //added by Chris Scott 128 /** constant for left indent body */ 129 public static final String LEFT_INDENT_BODY = "li"; 130 /** constant for left indent first */ 131 public static final String LEFT_INDENT_FIRST = "fi"; 132 /** constant for right indent body */ 133 public static final String RIGHT_INDENT_BODY = "ri"; 134 135 /** constant for center tab */ 136 public static final String TAB_CENTER = "tqc\\tx"; 137 /** constant for right tab */ 138 public static final String TAB_RIGHT = "tqr\\tx"; 139 /** constant for tab leader dots */ 140 public static final String TAB_LEADER_DOTS = "tldot"; 141 /** constant for tab leader hyphens */ 142 public static final String TAB_LEADER_HYPHEN = "tlhyph"; 143 /** constant for tab leader underscores */ 144 public static final String TAB_LEADER_UNDER = "tlul"; 145 /** constant for tab leader thick */ 146 public static final String TAB_LEADER_THICK = "tlth"; 147 /** constant for tab leader equals */ 148 public static final String TAB_LEADER_EQUALS = "tleq"; 149 150 /** Space before/after a paragraph */ 151 //these lines were added by Boris Pouderous 152 public static final String SPACE_BEFORE = "sb"; 153 /** Space after a paragraph */ 154 public static final String SPACE_AFTER = "sa"; 155 156 /** RtfText attributes: this must contain all allignment attributes names */ 157 public static final String[] ALIGNMENT = new String [] 158 { 159 ALIGN_CENTER, ALIGN_LEFT, ALIGN_RIGHT, ALIGN_JUSTIFIED, ALIGN_DISTRIBUTED 160 }; 161 162 /** RtfText attributes:: this must contain all border attribute names*/ 163 //this line added by Chris Scott, Westinghouse 164 public static final String[] BORDER = new String [] 165 { 166 BDR_BOTTOM_SINGLE, BDR_BOTTOM_DOUBLE, BDR_BOTTOM_EMBOSS, BDR_BOTTOM_DOTTED, 167 BDR_BOTTOM_DASH 168 }; 169 170 /** String array of indent constants */ 171 public static final String[] INDENT = new String [] 172 { 173 LEFT_INDENT_BODY, LEFT_INDENT_FIRST 174 }; 175 176 /** String array of tab constants */ 177 public static final String[] TABS = new String [] 178 { 179 TAB_CENTER, TAB_RIGHT, TAB_LEADER_DOTS, TAB_LEADER_HYPHEN, TAB_LEADER_UNDER, 180 TAB_LEADER_THICK, TAB_LEADER_EQUALS 181 }; 182 183 184 /** RtfText attributes: this must contain all attribute names */ 185 public static final String [] ATTR_NAMES = { 186 ATTR_BOLD, 187 ATTR_ITALIC, 188 ATTR_UNDERLINE, 189 ATTR_FONT_SIZE, 190 ATTR_FONT_FAMILY, 191 ATTR_FONT_COLOR, 192 ATTR_BACKGROUND_COLOR 193 }; 194 195 /** Create an RtfText in given IRtfTextContainer. 196 * @param str optional initial text content 197 */ RtfText(IRtfTextContainer parent, Writer w, String str, RtfAttributes attr)198 RtfText(IRtfTextContainer parent, Writer w, String str, RtfAttributes attr) 199 throws IOException { 200 super((RtfContainer)parent, w); 201 this.text = str; 202 this.attr = attr; 203 } 204 205 /** 206 * Write our text to the RTF stream 207 * @throws IOException for I/O problems 208 */ writeRtfContent()209 public void writeRtfContent() throws IOException { 210 writeChars: { 211 212 //these lines were added by Boris Pouderous 213 if (attr != null) { 214 writeAttributes(attr, new String[] {RtfText.SPACE_BEFORE}); 215 writeAttributes(attr, new String[] {RtfText.SPACE_AFTER}); 216 } 217 218 if (isTab()) { 219 writeControlWord("tab"); 220 } else if (isNewLine()) { 221 break writeChars; 222 } else if (isBold(true)) { 223 writeControlWord("b"); 224 } else if (isBold(false)) { 225 writeControlWord("b0"); 226 // TODO not optimal, consecutive RtfText with same attributes 227 // could be written without group marks 228 } else { 229 writeGroupMark(true); 230 if (attr != null && mustWriteAttributes()) { 231 writeAttributes(attr, RtfText.ATTR_NAMES); 232 } 233 RtfStringConverter.getInstance().writeRtfString(writer, text); 234 writeGroupMark(false); 235 } 236 } 237 } 238 239 /** true if our text attributes must be written */ mustWriteAttributes()240 private boolean mustWriteAttributes() { 241 return !isEmpty() && !isNbsp(); 242 } 243 244 /** IRtfTextContainer requirement: 245 * @return a copy of our attributes 246 * @throws FOPException if attributes cannot be cloned 247 */ getTextContainerAttributes()248 public RtfAttributes getTextContainerAttributes() throws FOPException { 249 if (attrib == null) { 250 return null; 251 } 252 try { 253 return (RtfAttributes)this.attrib.clone(); 254 } catch (CloneNotSupportedException e) { 255 throw new FOPException(e); 256 } 257 } 258 259 /** direct access to our text */ getText()260 String getText() { 261 return text; 262 } 263 264 /** direct access to our text */ setText(String str)265 void setText(String str) { 266 text = str; 267 } 268 269 /** 270 * Checks whether the text is empty. 271 * 272 * @return true If m_text is null\n 273 * false m_text is set 274 */ isEmpty()275 public boolean isEmpty() { 276 return text == null || text.trim().length() == 0; 277 } 278 279 /** 280 * True if text contains a single non-breaking space (#160). 281 * TODO make this more general and/or merge with isEmpty? -- what happen 282 * with empty paragraphs, if they will be removed, than NO, else ok 283 * 284 * @return true If m_text is character 160\n 285 * false m_text is not a nbsp 286 */ isNbsp()287 public boolean isNbsp() { 288 if (!isEmpty()) { 289 if (text.trim().length() == 1 && text.charAt(0) == CHAR_NBSP) { 290 return true; 291 } 292 } 293 return false; 294 } 295 296 /** 297 * @return true if the text is a tab character 298 */ isTab()299 public boolean isTab() { 300 return (text.trim().length() == 1 && text.charAt(0) == CHAR_TAB); 301 } 302 303 /** 304 * @return true if text is a newline character 305 */ isNewLine()306 public boolean isNewLine() { 307 return (text.trim().length() == 1 && text.charAt(0) == CHAR_NEW_LINE); 308 } 309 310 /** 311 * @param isStart set to true if processing the start of the text (??) 312 * @return true if text is bold 313 */ isBold(boolean isStart)314 public boolean isBold(boolean isStart) { 315 if (isStart) { 316 return (text.trim().length() == 1 && text.charAt(0) == CHAR_BOLD_START); 317 } else { 318 return (text.trim().length() == 1 && text.charAt(0) == CHAR_BOLD_END); 319 } 320 } 321 322 /** @return the attributes of our text */ getTextAttributes()323 public RtfAttributes getTextAttributes() { 324 return attr; 325 } 326 } 327