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 import java.awt.Color; 28 29 import org.w3c.dom.NodeList; 30 import org.w3c.dom.Node; 31 import org.w3c.dom.NamedNodeMap; 32 import org.w3c.dom.Element; 33 34 import org.openoffice.xmerge.Document; 35 import org.openoffice.xmerge.ConverterCapabilities; 36 import org.openoffice.xmerge.converter.xml.OfficeDocument; 37 import org.openoffice.xmerge.converter.xml.sxw.SxwDocument; 38 import org.openoffice.xmerge.converter.xml.*; 39 40 /** 41 * This class represents a color table in a WordSmith document. 42 * 43 * @author David Proulx 44 */ 45 class WseColorTable extends Wse { 46 47 private Color fgColors[]; 48 private Color bgColors[]; 49 50 /** 51 * Constructor to use when going from DOM to WordSmith 52 */ WseColorTable()53 public WseColorTable() { 54 fgColors = new Color[16]; 55 bgColors = new Color[16]; 56 57 // Always need these two! 58 fgColors[0] = Color.black; 59 bgColors[0] = Color.white; 60 61 } 62 63 /** 64 * Constructor to use when going from WordSmith to DOM. 65 * 66 * @param dataArray <code>byte</code> array. 67 * @param i The index. 68 */ WseColorTable(byte dataArray[], int i)69 public WseColorTable(byte dataArray[], int i) { 70 fgColors = new Color[16]; 71 bgColors = new Color[16]; 72 73 i += 2; // Skip leading "64" and table length field. 74 for (int k = 0; k < 16; k++) { 75 fgColors[k] = new Color(((int)dataArray[i+1]) & 0xFF, 76 ((int)dataArray[i+2]) & 0xFF, 77 ((int)dataArray[i+3]) & 0xFF); 78 i += 4; 79 } 80 for (int k = 0; k < 16; k++) { 81 bgColors[k] = new Color(((int)dataArray[i+1]) & 0xFF, 82 ((int)dataArray[i+2]) & 0xFF, 83 ((int)dataArray[i+3]) & 0xFF); 84 i += 4; 85 } 86 87 } 88 89 90 /** 91 * Compute the index of the first <code>byte</code> following the 92 * paragraph descriptor, assuming that 93 * <code>dataArray[startIndex]</code> is the beginning of a valid 94 * paragraph descriptor. 95 * 96 * @param dataArray <code>byte</code array. 97 * @param startIndex The start index. 98 * 99 * @return The index of the first <code>byte</code> following the 100 * paragraph description. 101 */ computeNewIndex(byte dataArray[], int startIndex)102 static int computeNewIndex(byte dataArray[], int startIndex) { 103 int tableLen = dataArray[startIndex + 1]; 104 tableLen &= 0xFF; // eliminate problems with sign-extension 105 return startIndex + tableLen + 2; 106 } 107 108 109 /** 110 * Return true if <code>dataArray[startIndex]</code> is the start 111 * of a valid paragraph descriptor. 112 * 113 * @param dataArray <code>byte</code> array. 114 * @param startIndex Start index. 115 * 116 * @return true if <code>dataArray[startIndex]</code> is the start 117 * of a valid paragraph descriptor, false otherwise. 118 */ isValid(byte dataArray[], int startIndex)119 static boolean isValid(byte dataArray[], int startIndex) { 120 try { 121 if (dataArray[startIndex] != 64) 122 return false; 123 int len = dataArray[startIndex + 1]; 124 len &= 0xFF; // eliminate problems with sign-extension 125 int temp = dataArray[startIndex + (int)len + 2]; // probe end of table 126 } catch (ArrayIndexOutOfBoundsException e) { 127 return false; 128 } 129 return true; 130 } 131 132 133 /** 134 * Return the number of bytes needed to represent this color table. 135 * 136 * @return The byte count. 137 */ getByteCount()138 int getByteCount() { 139 return (32 * 4) + 1 + 1; 140 } 141 142 143 /** 144 * Return a <code>byte</code> array representing this color table. 145 * 146 * @return <code>bytes</code> array representing this color table. 147 */ getBytes()148 byte[] getBytes() { 149 byte[] b = new byte[(32 * 4) + 1 + 1]; 150 b[0] = 0x40; 151 b[1] = (byte)128; 152 int i = 2; 153 // int indVal = 0xd8; 154 int indVal = 0; 155 156 for (int j = 0; j < 16; j++) { 157 b[i++] = (byte)indVal++; 158 if (fgColors[j] != null) { 159 b[i++] = (byte)fgColors[j].getRed(); 160 b[i++] = (byte)fgColors[j].getGreen(); 161 b[i++] = (byte)fgColors[j].getBlue(); 162 } else { 163 b[i++] = (byte)0; 164 b[i++] = (byte)0; 165 b[i++] = (byte)0; 166 } 167 } 168 169 for (int j = 0; j < 16; j++) { 170 b[i++] = (byte)indVal++; 171 if (bgColors[j] != null) { 172 b[i++] = (byte)bgColors[j].getRed(); 173 b[i++] = (byte)bgColors[j].getGreen(); 174 b[i++] = (byte)bgColors[j].getBlue(); 175 } else { 176 b[i++] = (byte)0xFF; 177 b[i++] = (byte)0xFF; 178 b[i++] = (byte)0xFF; 179 } 180 } 181 182 return b; 183 } 184 185 186 /** 187 * Return the index of the specified foreground or background 188 * <code>Color</code>. (If the color is not already in the table, 189 * it will be added.) 190 * 191 * Note that the implementation of this may include a "margin of 192 * error" to prevent the color table from being filled up too 193 * quickly. 194 * 195 * @param c The <code>Color</code>. 196 * @param foreground true if foreground color, false if background 197 * color 198 * 199 * @return The index of the specified foreground or background 200 * <code>Color</code>. 201 * 202 * DJP: how to handle table overflow? 203 */ findColor(Color c, boolean foreground)204 int findColor(Color c, boolean foreground) { 205 206 Color colorArray[] = foreground ? fgColors : bgColors; 207 208 for (int i = 0; i < 16; i++) { 209 if (colorArray[i] != null) { 210 if (colorArray[i].equals(c)) 211 return i; 212 } 213 else 214 break; // hit a null entry - no more colors in table! 215 } 216 217 // Color was not found in the table. Add it. 218 for (int i = 0; i < 16; i++) { 219 if (colorArray[i] == null) { 220 colorArray[i] = c; 221 return i; 222 } 223 } 224 return 0; // Default - we should never get here though. 225 } 226 227 228 /** 229 * Given an index, return the <code>Color</code> from the table. 230 * 231 * @param index The index 232 * @param foreground true if foreground color, false if background 233 * color 234 * 235 * @return The <code>Color</code> at the specified index. 236 */ getColor(int index, boolean foreground)237 Color getColor(int index, boolean foreground) { 238 239 Color colorArray[] = foreground ? fgColors : bgColors; 240 return colorArray[index]; 241 } 242 } 243 244