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.sxc.pexcel.records; 25 26 import java.io.OutputStream; 27 import java.io.InputStream; 28 import java.io.IOException; 29 import java.io.UnsupportedEncodingException; 30 import java.awt.Color; 31 32 import org.openoffice.xmerge.converter.xml.sxc.Format; 33 import org.openoffice.xmerge.util.Debug; 34 import org.openoffice.xmerge.util.EndianConverter; 35 import org.openoffice.xmerge.util.ColourConverter; 36 import org.openoffice.xmerge.converter.xml.sxc.pexcel.PocketExcelConstants; 37 38 39 /** 40 * Represents a BIFF Record descibing a font used 41 */ 42 public class FontDescription implements BIFFRecord { 43 44 private byte[] dwHeight = new byte[2]; 45 private byte[] grbit = new byte[2]; 46 private byte[] icvFore = new byte[2]; 47 private byte[] bls = new byte[2]; 48 private byte[] Reserved2 = new byte[2]; 49 private byte uls; 50 private byte bFamily; 51 private byte bCharSet; 52 private byte Reserved3; 53 private byte cch; 54 private byte[] rgch; 55 56 public static final int UNDERLINE = 0x01; 57 public static final int ITALIC = 0x02; 58 FontDescription(Format fmt)59 public FontDescription(Format fmt) throws IOException { 60 61 Debug.log(Debug.TRACE,"Building FontDescriptor based on Format : " + fmt); 62 63 this.dwHeight = EndianConverter.writeShort((short) (fmt.getFontSize()*20)); 64 65 grbit = new byte[] {(byte)0x00, (byte)0x00}; 66 bls = EndianConverter.writeShort((short) 400); 67 uls = 0; 68 69 if (fmt.getAttribute(Format.ITALIC)) 70 grbit[0] |= ITALIC; 71 72 if (fmt.getAttribute(Format.BOLD)) 73 bls = EndianConverter.writeShort((short) 700); 74 75 if (fmt.getAttribute(Format.UNDERLINE)) 76 uls |= UNDERLINE; 77 78 79 bFamily = 0; 80 bCharSet = 0; 81 82 String fontName = fmt.getFontName(); 83 if( !fontName.equals("Tahoma") && 84 !fontName.equals("Courier New")) { 85 // We will set our default font to be Tahoma 86 fontName = new String("Tahoma"); 87 } 88 89 cch = (byte) fontName.length(); 90 rgch = fontName.getBytes("UTF-16LE"); 91 92 Color foreground = fmt.getForeground(); 93 if( foreground != null ) { 94 ColourConverter cc = new ColourConverter(PocketExcelConstants.cLookup); 95 icvFore = EndianConverter.writeShort(cc.convertFromRGB(foreground)); 96 } else { 97 icvFore = new byte[] {(byte)0xFF,(byte)0x00}; 98 } 99 100 Reserved2 = EndianConverter.writeShort((short) 0); 101 Reserved3 = 0; 102 103 } 104 105 /** 106 * Tests if this font descriptor defines italic 107 * 108 * @return true if italic otherwise false 109 */ isItalic()110 public boolean isItalic() { 111 112 return (EndianConverter.readShort(grbit) == 2); 113 } 114 115 /** 116 * Tests if this font descriptor defines underline 117 * 118 * @return true if underline otherwise false 119 */ isUnderline()120 public boolean isUnderline() { 121 122 return (uls == 1); 123 } 124 125 /** 126 * Tests if this font descriptor defines bold 127 * 128 * @return true if bold otherwise false 129 */ isBold()130 public boolean isBold() { 131 132 return (EndianConverter.readShort(bls) == 700); 133 } 134 135 /** 136 * Get the background color this format uses 137 * 138 * @return the background color 139 */ getForeground()140 public Color getForeground() { 141 short rgb = EndianConverter.readShort(icvFore); 142 Color c = null; 143 if(rgb!=0xFF) { 144 ColourConverter cc = new ColourConverter(PocketExcelConstants.cLookup); 145 c = cc.convertToRGB(rgb); 146 } 147 return c; 148 } 149 150 /** 151 * Compares current font descriptor against one passed in 152 * 153 * @return true if attrbitues are the same 154 */ compareTo(FontDescription rhs)155 public boolean compareTo(FontDescription rhs) { 156 157 if(EndianConverter.readShort(icvFore) != 158 EndianConverter.readShort(rhs.icvFore)) 159 return false; 160 161 if (EndianConverter.readShort(dwHeight) != 162 EndianConverter.readShort(dwHeight)) 163 return false; 164 165 if (this.getFont() != rhs.getFont()) 166 return false; 167 168 if (this.isBold() != rhs.isBold()) 169 return false; 170 171 if (this.isUnderline() != rhs.isUnderline()) 172 return false; 173 174 if (this.isItalic() != rhs.isItalic()) 175 return false; 176 177 return true; 178 } 179 180 181 /** 182 * Constructs a Font Description from the <code>InputStream</code> 183 * 184 * @param is InputStream containing a <code>FontDescription</code> 185 */ FontDescription(InputStream is)186 public FontDescription(InputStream is) throws IOException { 187 read(is); 188 } 189 190 /** 191 * Get the hex code for this particular <code>BIFFRecord</code> 192 * 193 * @return the hex code for <code>FontDescription</code> 194 */ getBiffType()195 public short getBiffType() { 196 return PocketExcelConstants.FONT_DESCRIPTION; 197 } 198 199 /** 200 * Get the Font size 201 * 202 */ getFontSize()203 public int getFontSize() { 204 return EndianConverter.readShort(dwHeight)/20; 205 } 206 207 /** 208 * Get the font name 209 * 210 */ getFont()211 public String getFont() { 212 213 String name; 214 215 try { 216 name = new String(rgch, "UTF-16LE"); 217 } catch (UnsupportedEncodingException e){ 218 name = "Tahoma"; 219 } 220 return name; 221 } 222 223 /** 224 * Constructs a Font Description from the <code>InputStream</code> 225 * 226 * @param input InputStream containing a <code>FontDescription</code> 227 */ read(InputStream input)228 public int read(InputStream input) throws IOException { 229 230 int numOfBytesRead = input.read(dwHeight); 231 numOfBytesRead += input.read(grbit); 232 numOfBytesRead += input.read(icvFore); 233 numOfBytesRead += input.read(bls); 234 numOfBytesRead += input.read(Reserved2); 235 uls = (byte) input.read(); 236 bFamily = (byte) input.read(); 237 bCharSet = (byte) input.read(); 238 Reserved3 = (byte) input.read(); 239 cch = (byte) input.read(); 240 numOfBytesRead += 5; 241 242 rgch = new byte[cch*2]; 243 input.read(rgch, 0, cch*2); 244 245 Debug.log(Debug.TRACE,"\tdwHeight : "+ EndianConverter.readShort(dwHeight) + 246 " grbit : " + EndianConverter.readShort(grbit) + 247 " bls : " + EndianConverter.readShort(bls) + 248 " uls : " + uls + 249 "\n\tFamily : " + bFamily + 250 " bCharSet : " + bCharSet + 251 " cch : " + cch + 252 " rgch : " + new String(rgch,"UTF-16LE")); 253 254 return numOfBytesRead; 255 } 256 write(OutputStream output)257 public void write(OutputStream output) throws IOException { 258 259 output.write(getBiffType()); 260 output.write(dwHeight); 261 output.write(grbit); 262 output.write(icvFore); 263 output.write(bls); 264 output.write(Reserved2); 265 output.write(uls); 266 output.write(bFamily); 267 output.write(bCharSet); 268 output.write(Reserved3); 269 output.write(cch); 270 output.write(rgch); 271 272 Debug.log(Debug.TRACE,"Writing FontDescription record"); 273 } 274 275 } 276