org.apache.poi.hwpf.model.OldFfn Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of apache-poi-ooxml Show documentation
Show all versions of apache-poi-ooxml Show documentation
The Apache Commons Codec package contains simple encoder and decoders for
various formats such as Base64 and Hexadecimal. In addition to these
widely used encoders and decoders, the codec package also maintains a
collection of phonetic encoding utilities.
/* ====================================================================
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.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.common.usermodel.fonts.FontCharset;
import org.apache.poi.util.Internal;
import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.util.StringUtil;
import static org.apache.logging.log4j.util.Unbox.box;
/**
* Word 6.0 Font information
*/
@Internal
public final class OldFfn {
private static final Logger LOG = LogManager.getLogger(OldFfn.class);
private final 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 = buf[offset];
offset += 1;
if (offset + fontDescriptionLength > fontTableEnd) {
LOG.atWarn().log("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;
FontCharset wmfCharset = FontCharset.valueOf(chs & 0xff);
if (wmfCharset == null) {
LOG.atWarn().log("Couldn't find font for type: {}", box((chs & 0xff)));
} else {
charset = wmfCharset.getCharset();
}
charset = charset == null ? StringUtil.WIN_1252 : charset;
offset += LittleEndianConsts.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 += LittleEndianConsts.BYTE_SIZE;
int fontNameLength = -1;
for (int i = offset; i < fontTableEnd; i++) {
if (buf[i] == 0) {
fontNameLength = i - offset;
break;
}
}
if (fontNameLength == -1) {
LOG.atWarn().log("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 = LittleEndianConsts.INT_SIZE + LittleEndianConsts.BYTE_SIZE + LittleEndianConsts.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 +
'}';
}
}