/* * 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 org.pentaho.reporting.libraries.fonts.encoding.EncodingUtility; import org.pentaho.reporting.libraries.fonts.io.FileFontDataInputSource; import org.pentaho.reporting.libraries.fonts.io.FontDataInputSource; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.util.Arrays; /** * 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; } }