/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2006 - 2013 Pentaho Corporation and Contributors. All rights reserved.
*/
package org.pentaho.reporting.libraries.fonts.pfm;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import org.pentaho.reporting.libraries.fonts.encoding.EncodingUtility;
import org.pentaho.reporting.libraries.fonts.io.FileFontDataInputSource;
import org.pentaho.reporting.libraries.fonts.io.FontDataInputSource;
/**
* Creation-Date: 21.07.2007, 15:27:07
*
* @author Thomas Morgner
*/
public class PfmFont
{
private String filename;
private FontDataInputSource input;
private transient byte[] readBuffer;
private PfmFontHeader header;
private PfmExtension extension;
private String fontName;
private String familyName;
private boolean embeddable;
public PfmFont(final File font, final boolean embeddable) throws IOException
{
this(new FileFontDataInputSource(font), embeddable);
}
public PfmFont(final FontDataInputSource input, final boolean embeddable) throws IOException
{
this.embeddable = embeddable;
this.input = input;
this.filename = input.getFileName();
this.header = new PfmFontHeader(readFully(0, PfmFontHeader.LENGTH));
this.extension = new PfmExtension(readFully(PfmFontHeader.LENGTH, PfmExtension.LENGTH));
final int facePtr = this.header.getFacePtr();
if (facePtr == 0)
{
throw new IOException("This font is not valid, it does not define a font-name");
}
final byte[] familyNameRaw = readZString(facePtr);
this.familyName = EncodingUtility.encode(familyNameRaw, header.getEncoding());
final int driverInfo = this.extension.getDriverInfo();
if (driverInfo > 0)
{
final byte[] fontName = readZString(driverInfo);
this.fontName = EncodingUtility.encode(fontName, "ASCII");
}
else
{
this.fontName = familyName;
}
}
/**
* IText's PFM reader is buggy. We have to check for the bug or we will run into troubles.
*
* @return
*/
public boolean isItextCompatible()
{
final int driverInfo = this.extension.getDriverInfo();
if (driverInfo < 75 || driverInfo > 512)
{
embeddable = false;
return false;
}
return true;
}
public String getFontName()
{
return fontName;
}
public String getFamilyName()
{
return familyName;
}
public PfmFontHeader getHeader()
{
return header;
}
public String getFilename()
{
return filename;
}
public FontDataInputSource getInput()
{
return input;
}
public void dispose()
{
input.dispose();
}
protected byte[] readFully(final long offset, final int length)
throws IOException
{
if (readBuffer == null)
{
readBuffer = new byte[Math.max(8192, length)];
}
else if (readBuffer.length < length)
{
readBuffer = new byte[length];
}
input.readFullyAt(offset, readBuffer, length);
if ((readBuffer.length - length) > 0)
{
Arrays.fill(readBuffer, length, readBuffer.length, (byte) 0);
}
return readBuffer;
}
protected byte[] readZString (final long offset) throws IOException
{
long position = offset;
final ByteArrayOutputStream bout = new ByteArrayOutputStream();
int data;
while ((data = input.readAt(position)) > 0)
{
bout.write(data);
position += 1;
}
return bout.toByteArray();
}
public boolean isEmbeddable()
{
return embeddable;
}
}