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.wordsmith; 25 26 import java.io.IOException; 27 28 import org.w3c.dom.NodeList; 29 import org.w3c.dom.Node; 30 import org.w3c.dom.NamedNodeMap; 31 import org.w3c.dom.Element; 32 33 import org.openoffice.xmerge.Document; 34 import org.openoffice.xmerge.ConverterCapabilities; 35 import org.openoffice.xmerge.converter.xml.OfficeDocument; 36 import org.openoffice.xmerge.converter.xml.sxw.SxwDocument; 37 import org.openoffice.xmerge.converter.xml.*; 38 39 40 /** 41 * This class represents a paragraph in a WordSmith document. 42 * (A paragraph is "5" followed by 12 bytes of attributes.) 43 * 44 * @author David Proulx 45 */ 46 class WsePara extends Wse { 47 48 private byte spaceBefore = 0; 49 private byte spaceAfter = 0; 50 private byte leftIndent = 0; 51 private byte firstIndent = 0; 52 private byte rightIndent = 0; 53 private byte misc = 0; 54 private byte style = 0; 55 private byte lineSpace = 0; 56 private byte outline = 0; 57 private byte reserved = 0; 58 59 private static final byte LS_EXACTLY = (byte)0xC0; 60 private static final byte LS_ATLEAST = (byte)0x80; 61 private static final byte LS_MULTIPLE = (byte)0x40; 62 private static final byte LS_VALUEMASK = (byte)0x3F; 63 64 private static final byte ALIGN_RIGHT = (byte)2; 65 private static final byte ALIGN_LEFT = (byte)0; 66 private static final byte ALIGN_CENTER = (byte)1; 67 private static final byte ALIGN_JUST = (byte)3; 68 69 private StyleCatalog sc = null; 70 71 72 /** 73 * Constructor for use when going from DOM to WordSmith. 74 * 75 * @param p The paragraph style. 76 * @param sc The <code>StyleCatalog</code>. 77 */ WsePara(ParaStyle p, StyleCatalog sc)78 public WsePara(ParaStyle p, StyleCatalog sc) { 79 this.sc = sc; 80 ParaStyle ps = (ParaStyle)p.getResolved(); 81 82 if (ps.isAttributeSet(ParaStyle.MARGIN_LEFT)) { 83 double temp = ps.getAttribute(ParaStyle.MARGIN_LEFT) * 1.6 / 100; 84 leftIndent = (byte) temp; 85 if ((temp - leftIndent) > 0.5) leftIndent++; 86 } 87 88 if (ps.isAttributeSet(ParaStyle.MARGIN_RIGHT)) { 89 double temp = ps.getAttribute(ParaStyle.MARGIN_RIGHT) * 1.6 / 100; 90 rightIndent = (byte) temp; 91 if ((temp - rightIndent) > 0.5) rightIndent++; 92 } 93 94 if (ps.isAttributeSet(ParaStyle.TEXT_INDENT)) { 95 double temp = ps.getAttribute(ParaStyle.TEXT_INDENT) * 1.6 / 100; 96 firstIndent = (byte) temp; 97 if ((temp - firstIndent) > 0.5) firstIndent++; 98 } 99 100 if (ps.isAttributeSet(ParaStyle.MARGIN_TOP)) { 101 double temp = ps.getAttribute(ParaStyle.MARGIN_TOP) * 1.6 / 100; 102 spaceBefore = (byte) temp; 103 if ((temp - spaceBefore) > 0.5) spaceBefore++; 104 } 105 106 if (ps.isAttributeSet(ParaStyle.MARGIN_BOTTOM)) { 107 double temp = ps.getAttribute(ParaStyle.MARGIN_BOTTOM) * 1.6 / 100; 108 spaceAfter = (byte) temp; 109 if ((temp - spaceAfter) > 0.5) spaceAfter++; 110 } 111 112 if (ps.isAttributeSet(ParaStyle.LINE_HEIGHT)) { 113 int lh = ps.getAttribute(ParaStyle.LINE_HEIGHT); 114 if ((lh & ~ParaStyle.LH_VALUEMASK) == 0) 115 lineSpace = (byte)(LS_MULTIPLE | (lh * 2)); 116 else if ((lh & ParaStyle.LH_PCT) != 0) { 117 lh = (lh & ParaStyle.LH_VALUEMASK) / 100; 118 lineSpace = (byte)(LS_MULTIPLE | (lh * 2)); 119 } 120 // DJP: handle other cases.... 121 } 122 123 if (ps.isAttributeSet(ParaStyle.TEXT_ALIGN)) { 124 125 int val = ps.getAttribute(ParaStyle.TEXT_ALIGN); 126 127 switch (val) { 128 case ParaStyle.ALIGN_RIGHT: 129 misc = ALIGN_RIGHT; 130 break; 131 case ParaStyle.ALIGN_LEFT: 132 misc = ALIGN_LEFT; 133 break; 134 case ParaStyle.ALIGN_CENTER: 135 misc = ALIGN_CENTER; 136 break; 137 case ParaStyle.ALIGN_JUST: 138 misc = ALIGN_JUST; 139 break; 140 } 141 } 142 143 } 144 145 146 /** 147 * Constructor for use when going from WordSmith to DOM. 148 * Assumes <code>dataArray[startIndex]</code> is the first 149 * <code>byte</code> of a valid WordSmith paragraph descriptor. 150 * 151 * @param dataArray <code>byte</code> array. 152 * @param startIndex The start index. 153 */ WsePara(byte dataArray[], int startIndex)154 public WsePara(byte dataArray[], int startIndex) { 155 spaceBefore = dataArray[startIndex + 1]; 156 spaceAfter = dataArray[startIndex + 2]; 157 leftIndent = dataArray[startIndex + 3]; 158 firstIndent = dataArray[startIndex + 4]; 159 rightIndent = dataArray[startIndex + 5]; 160 misc = dataArray[startIndex + 6]; 161 style = dataArray[startIndex + 7]; 162 lineSpace = dataArray[startIndex + 8]; 163 outline = dataArray[startIndex + 9]; 164 } 165 166 167 /** 168 * Compute the index of the first <code>byte</code> following the 169 * paragraph descriptor, assuming that 170 * <code>dataArray[startIndex]</code> is the beginning of a valid 171 * paragraph descriptor. 172 * 173 * @param dataArray <code>byte</code> array. 174 * @param startIndex The start index. 175 * 176 * @return The index of the first <code>byte</code> following the 177 * paragraph description. 178 */ computeNewIndex(byte dataArray[], int startIndex)179 static int computeNewIndex(byte dataArray[], int startIndex) { 180 return startIndex + 13; 181 } 182 183 184 /** 185 * Return true if <code>dataArray[startIndex]</code> is the start 186 * of a valid paragraph descriptor. 187 * 188 * @param dataArray <code>byte</code> array. 189 * @param startIndex The start index. 190 * 191 * @return true if <code>dataArray[startIndex]</code> is the start 192 * of a valid paragraph descriptor, false otherwise. 193 */ isValid(byte dataArray[], int startIndex)194 static boolean isValid(byte dataArray[], int startIndex) { 195 return (dataArray[startIndex] == 5); 196 } 197 198 /** 199 * Return the number of bytes needed to represent this paragraph. 200 * 201 * @return The number of bytes needed to represent this paragraph. 202 */ getByteCount()203 int getByteCount() { 204 return 13; 205 } 206 207 /** 208 * Return an <code>byte</code> array representing this paragraph. 209 * 210 * @return An <code>byte</code> array representing this paragraph. 211 */ getBytes()212 byte[] getBytes() { 213 byte b[] = new byte[13]; 214 215 b[0] = 5; 216 b[1] = spaceBefore; 217 b[2] = spaceAfter; 218 b[3] = leftIndent; 219 b[4] = firstIndent; 220 b[5] = rightIndent; 221 b[6] = misc; 222 b[7] = style; 223 b[8] = lineSpace; 224 b[9] = outline; 225 b[10] = reserved; 226 b[11] = 0; 227 b[12] = 0; 228 229 return b; 230 } 231 232 /** 233 * Return a <code>ParaStyle</code> that reflects the formatting of 234 * this run. 235 * 236 * @return A <code>ParaStyle</code> that reflects the formatting 237 * of this run. 238 */ makeStyle()239 ParaStyle makeStyle() { 240 /* Csaba: Commented out the LINE_HEIGHT syle, because there was no 241 incoming data for that style. It was resulting a zero line 242 height in the xml document, ie. the doc looked empty. 243 */ 244 int attrs[] = { ParaStyle.MARGIN_LEFT, ParaStyle.MARGIN_RIGHT, 245 ParaStyle.TEXT_INDENT, //ParaStyle.LINE_HEIGHT, 246 ParaStyle.MARGIN_TOP, ParaStyle.MARGIN_BOTTOM, 247 ParaStyle.TEXT_ALIGN }; 248 String values[] = new String[attrs.length]; 249 double temp; 250 251 temp = leftIndent / 1.6; 252 values[0] = (new Double(temp)).toString() + "mm"; 253 254 temp = rightIndent / 1.6; 255 values[1] = (new Double(temp)).toString() + "mm"; 256 257 temp = firstIndent / 1.6; 258 values[2] = (new Double(temp)).toString() + "mm"; 259 260 /* if ((lineSpace & LS_MULTIPLE) != 0) { 261 temp = (lineSpace & LS_VALUEMASK) / 2; 262 temp *= 100; 263 values[3] = (new Double(temp)).toString() + "%"; 264 } else { 265 values[3] = (new Double(temp)).toString() + "mm"; 266 // DJP: handle other cases 267 } 268 */ 269 temp = spaceBefore / 1.6; 270 // values[4] = (new Double(temp)).toString() + "mm"; 271 values[3] = (new Double(temp)).toString() + "mm"; 272 273 temp = spaceAfter / 1.6; 274 // values[5] = (new Double(temp)).toString() + "mm"; 275 values[4] = (new Double(temp)).toString() + "mm"; 276 277 switch (misc) { 278 279 // case ALIGN_RIGHT: values[6] = "right"; break; 280 // case ALIGN_LEFT: values[6] = "left"; break; 281 // case ALIGN_CENTER:values[6] = "center"; break; 282 // case ALIGN_JUST: values[6] = "justified"; break; 283 284 case ALIGN_RIGHT: values[5] = "right"; break; 285 case ALIGN_LEFT: values[5] = "left"; break; 286 case ALIGN_CENTER:values[5] = "center"; break; 287 case ALIGN_JUST: values[5] = "justified"; break; 288 } 289 ParaStyle x = new ParaStyle(null, "paragraph", null, attrs, 290 values, sc); 291 292 return x; 293 } 294 } 295 296