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(rhs.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