1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 package org.openoffice.xmerge.converter.xml.sxw.pocketword; 25 26 import org.openoffice.xmerge.converter.xml.TextStyle; 27 28 import org.openoffice.xmerge.util.EndianConverter; 29 30 import org.openoffice.xmerge.util.ColourConverter; 31 32 import java.io.ByteArrayOutputStream; 33 import java.io.IOException; 34 35 /** 36 * This class represents a portion of text with a particular formatting style. 37 * The style may differ from the default style of the paragraph of which it 38 * is part. 39 * 40 * @author Mark Murnane 41 * @version 1.1 42 */ 43 class ParagraphTextSegment implements PocketWordConstants { 44 45 private String pText; 46 private TextStyle pStyle; 47 48 49 /** 50 * <p>Initialise a new <code>ParagraphTextSegment</p>. 51 * <p>Both parameters may be <code>null</code>.</p> 52 * 53 * @param data The text of this segment. 54 * @param style The style describing this segment. 55 */ ParagraphTextSegment(String data, TextStyle style)56 public ParagraphTextSegment (String data, TextStyle style) { 57 pText = data; 58 pStyle = style; 59 } 60 61 /** 62 * <p>Sets the text for this segment.</p> 63 * 64 * @param data The text of this segment. 65 */ setText(String data)66 public void setText (String data) { 67 pText = data; 68 } 69 70 /** 71 * <p>Gets the text for this segment.</p> 72 * 73 * @return The text of this segment. 74 */ getText()75 public String getText () { 76 return pText; 77 } 78 79 80 /** 81 * <p>Sets the style for this segment.</p> 82 * 83 * @param style The style describing this segment. 84 */ setStyle(TextStyle style)85 public void setStyle (TextStyle style) { 86 pStyle = style; 87 } 88 89 90 /** 91 * <p>Gets the style for this segment.</p> 92 * 93 * @return The style describing this segment. 94 */ getStyle()95 public TextStyle getStyle () { 96 return pStyle; 97 } 98 99 100 /** 101 * <p>Returns the string data for this text segment wrapped with the 102 * appropriate byte codes for the formatting settings used.</p> 103 * 104 * @return <code>byte</code> array containing formatted text in Pocket Word 105 * format. 106 */ getData()107 public byte[] getData () { 108 ByteArrayOutputStream data = new ByteArrayOutputStream(); 109 110 boolean colourSet = false; 111 boolean boldSet = false; 112 boolean italicSet = false; 113 boolean underlineSet = false; 114 boolean strikeSet = false; 115 boolean highlightSet = false; 116 117 // TODO: Font changes need to be worked out here 118 119 try { 120 if (pStyle != null) { 121 if (pStyle.getFontColor() != null) { 122 ColourConverter cc = new ColourConverter(); 123 short colourCode = cc.convertFromRGB(pStyle.getFontColor()); 124 if (colourCode != 0) { // not black 125 data.write(COLOUR_TAG); 126 data.write(EndianConverter.writeShort(colourCode)); 127 colourSet = true; 128 } 129 } 130 if (pStyle.isSet(TextStyle.BOLD) && pStyle.getAttribute(TextStyle.BOLD)) { 131 data.write(new byte[] { FONT_WEIGHT_TAG, FONT_WEIGHT_BOLD, 0x00 } ); 132 boldSet = true; 133 } 134 if (pStyle.isSet(TextStyle.ITALIC) && pStyle.getAttribute(TextStyle.ITALIC)) { 135 data.write(new byte[] { ITALIC_TAG, 0x01 } ); 136 italicSet = true; 137 } 138 if (pStyle.isSet(TextStyle.UNDERLINE) && pStyle.getAttribute(TextStyle.UNDERLINE)) { 139 data.write(new byte[] { UNDERLINE_TAG, 0x01 } ); 140 underlineSet = true; 141 } 142 if (pStyle.isSet(TextStyle.STRIKETHRU) && pStyle.getAttribute(TextStyle.STRIKETHRU)) { 143 data.write(new byte[] { STRIKETHROUGH_TAG, 0x01 } ); 144 strikeSet = true; 145 } 146 if (pStyle.getBackgroundColor() != null) { 147 data.write(new byte[] { HIGHLIGHT_TAG, 0x01 } ); 148 highlightSet = true; 149 } 150 } 151 152 153 // Now write out the data 154 if (!pText.equals("\t")) { 155 data.write(pText.getBytes()); 156 } 157 else { 158 /* 159 * Tabs are a special case. They are represented by Pocket Word 160 * as the LE sequence 0xC4 0x04. 161 */ 162 data.write(new byte[] { (byte)0xC4, 0x04 } ); 163 } 164 165 166 // Now close out any of the settings changes 167 if (colourSet) { 168 /* 169 * Colours may change without changing back to black, but 170 * without knowing what the previous colour was, the only 171 * way to ensure correct conversion is to restore to black and 172 * let the next segment change the colour again. 173 */ 174 data.write(new byte[] { COLOUR_TAG, 0x00, 0x00 } ); 175 } 176 if (boldSet) { 177 data.write(new byte[] { FONT_WEIGHT_TAG, FONT_WEIGHT_NORMAL, 0x00 } ); 178 } 179 if (italicSet) { 180 data.write(new byte[] { ITALIC_TAG, 0x00 } ); 181 } 182 if (underlineSet) { 183 data.write(new byte[] { UNDERLINE_TAG, 0x00 } ); 184 } 185 if (strikeSet) { 186 data.write(new byte[] { STRIKETHROUGH_TAG, 0x00 } ); 187 } 188 if (highlightSet) { 189 data.write(new byte[] { HIGHLIGHT_TAG, 0x00 } ); 190 } 191 } 192 catch (IOException ioe) { 193 // Should never occur in a memory based stream 194 } 195 196 return data.toByteArray(); 197 } 198 } 199