162 lines
5.4 KiB
Java
162 lines
5.4 KiB
Java
/* ====================================================================
|
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
|
contributor license agreements. See the NOTICE file distributed with
|
|
this work for additional information regarding copyright ownership.
|
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
|
(the "License"); you may not use this file except in compliance with
|
|
the License. You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
==================================================================== */
|
|
|
|
package org.apache.poi.hwpf.model;
|
|
|
|
import java.nio.charset.Charset;
|
|
|
|
import org.apache.poi.hwmf.record.HwmfFont;
|
|
import org.apache.poi.util.Internal;
|
|
import org.apache.poi.util.LittleEndian;
|
|
import org.apache.poi.util.POILogFactory;
|
|
import org.apache.poi.util.POILogger;
|
|
import org.apache.poi.util.StringUtil;
|
|
|
|
/**
|
|
* Word 6.0 Font information
|
|
*/
|
|
@Internal
|
|
public final class OldFfn {
|
|
|
|
private static final POILogger logger = POILogFactory.getLogger(OldFfn.class);
|
|
|
|
private byte _chs;// character set identifier
|
|
|
|
private final String fontName;
|
|
private final String altFontName;
|
|
|
|
private final int length; //length in bytes for this record
|
|
|
|
/**
|
|
* try to read an OldFfn starting at offset; read no farther than end
|
|
*
|
|
* @param buf buffer from which to read
|
|
* @param offset offset at which to start
|
|
* @param fontTableEnd read no farther than this
|
|
* @return an OldFfn or null if asked to read beyond end
|
|
*/
|
|
static OldFfn build(byte[] buf, int offset, int fontTableEnd) {
|
|
int start = offset;
|
|
//preliminary bytes
|
|
if (offset + 6 > fontTableEnd) {
|
|
return null;
|
|
}
|
|
//first byte
|
|
short fontDescriptionLength = (short) buf[offset];
|
|
offset += 1;
|
|
if (offset + fontDescriptionLength > fontTableEnd) {
|
|
logger.log(POILogger.WARN, "Asked to read beyond font table end. Skipping font");
|
|
return null;
|
|
}
|
|
|
|
//no idea what these 3 bytes do
|
|
offset += 3;
|
|
byte chs = buf[offset];
|
|
Charset charset = null;
|
|
HwmfFont.WmfCharset wmfCharset = HwmfFont.WmfCharset.valueOf(chs & 0xff);
|
|
if (wmfCharset == null) {
|
|
logger.log(POILogger.WARN, "Couldn't find font for type: " + (chs & 0xff));
|
|
} else {
|
|
charset = wmfCharset.getCharset();
|
|
}
|
|
charset = charset == null ? StringUtil.WIN_1252 : charset;
|
|
offset += LittleEndian.BYTE_SIZE;
|
|
//if this byte here == 7, it _may_ signify existence of
|
|
//an altername font name
|
|
|
|
//not sure what the byte after the _chs does
|
|
offset += LittleEndian.BYTE_SIZE;
|
|
int fontNameLength = -1;
|
|
for (int i = offset; i < fontTableEnd; i++) {
|
|
if (buf[i] == 0) {
|
|
fontNameLength = i - offset;
|
|
break;
|
|
}
|
|
}
|
|
if (fontNameLength == -1) {
|
|
logger.log(POILogger.WARN, "Couldn't find the zero-byte delimited font name length");
|
|
return null;
|
|
}
|
|
String fontName = new String(buf, offset, fontNameLength, charset);
|
|
String altFontName = null;
|
|
int altFontNameLength = -1;
|
|
offset += fontNameLength + 1;
|
|
if (offset - start < fontDescriptionLength) {
|
|
for (int i = offset; i <= start + fontDescriptionLength; i++) {
|
|
if (buf[i] == 0) {
|
|
altFontNameLength = i - offset;
|
|
break;
|
|
}
|
|
}
|
|
if (altFontNameLength > -1) {
|
|
altFontName = new String(buf, offset, altFontNameLength, charset);
|
|
}
|
|
}
|
|
//reset to 0 for length calculation
|
|
altFontNameLength = (altFontNameLength < 0) ? 0 : altFontNameLength + 1;//add one for zero byte
|
|
|
|
int len = LittleEndian.INT_SIZE + LittleEndian.BYTE_SIZE + LittleEndian.BYTE_SIZE +//6 starting bytes
|
|
fontNameLength + altFontNameLength + 1;//+1 is for the zero byte
|
|
//this len should == fontDescriptionLength
|
|
|
|
return new OldFfn(chs, fontName, altFontName, len);
|
|
|
|
}
|
|
|
|
public OldFfn(byte charsetIdentifier, String fontName, String altFontName, int length) {
|
|
this._chs = charsetIdentifier;
|
|
this.fontName = fontName;
|
|
this.altFontName = altFontName;
|
|
this.length = length;
|
|
}
|
|
|
|
public byte getChs() {
|
|
return _chs;
|
|
}
|
|
|
|
public String getMainFontName() {
|
|
return fontName;
|
|
}
|
|
|
|
/**
|
|
* @return altFontName if it exists, null otherwise
|
|
*/
|
|
public String getAltFontName() {
|
|
return altFontName;
|
|
}
|
|
|
|
|
|
/**
|
|
* @return length in bytes for this record
|
|
*/
|
|
public int getLength() {
|
|
return length;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "OldFfn{" +
|
|
"_chs=" + (_chs & 0xff) +
|
|
", fontName='" + fontName + '\'' +
|
|
", altFontName='" + altFontName + '\'' +
|
|
", length=" + length +
|
|
'}';
|
|
}
|
|
}
|
|
|
|
|