/*
* $Id: OTFontCollection.java,v 1.6 2010-08-10 11:38:11 davidsch Exp $
*
* Typecast - The Font Development Environment
*
* Copyright (c) 2004 David Schweinsberg
*
* Licensed 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 jogamp.graph.font.typecast.ot;
import java.io.File;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import jogamp.graph.font.typecast.ot.mac.ResourceHeader;
import jogamp.graph.font.typecast.ot.mac.ResourceMap;
import jogamp.graph.font.typecast.ot.mac.ResourceReference;
import jogamp.graph.font.typecast.ot.mac.ResourceType;
import jogamp.graph.font.typecast.ot.table.DirectoryEntry;
import jogamp.graph.font.typecast.ot.table.TTCHeader;
import jogamp.graph.font.typecast.ot.table.Table;
/**
*
* @author <a href="mailto:davidsch@dev.java.net">David Schweinsberg</a>
* @version $Id: OTFontCollection.java,v 1.6 2010-08-10 11:38:11 davidsch Exp $
*/
public class OTFontCollection {
private String _pathName;
private String _fileName;
private TTCHeader _ttcHeader;
private OTFont[] _fonts;
private final ArrayList<Table> _tables = new ArrayList<Table>();
private boolean _resourceFork = false;
/** Creates new FontCollection */
protected OTFontCollection() {
}
/**
* @param file The OpenType font file
*/
public static OTFontCollection create(final File file) throws IOException {
final OTFontCollection fc = new OTFontCollection();
fc.read(file);
return fc;
}
/**
* @param istream The OpenType font input stream
* @param streamLen the length of the OpenType font segment in the stream
*/
public static OTFontCollection create(final InputStream istream, final int streamLen) throws IOException {
final OTFontCollection fc = new OTFontCollection();
fc.read(istream, streamLen);
return fc;
}
public String getPathName() {
return _pathName;
}
public String getFileName() {
return _fileName;
}
public OTFont getFont(final int i) {
return _fonts[i];
}
public int getFontCount() {
return _fonts.length;
}
public TTCHeader getTtcHeader() {
return _ttcHeader;
}
public Table getTable(final DirectoryEntry de) {
for (int i = 0; i < _tables.size(); i++) {
final Table table = _tables.get(i);
if ((table.getDirectoryEntry().getTag() == de.getTag()) &&
(table.getDirectoryEntry().getOffset() == de.getOffset())) {
return table;
}
}
return null;
}
public void addTable(final Table table) {
_tables.add(table);
}
/**
* @param file The OpenType font file
*/
protected void read(File file) throws IOException {
_pathName = file.getPath();
_fileName = file.getName();
if (!file.exists()) {
throw new IOException("File <"+file.getName()+"> doesn't exist.");
}
// Do we need to modify the path name to deal with font resources
// in a Mac resource fork?
if (file.length() == 0) {
file = new File(file, "..namedfork/rsrc");
if (!file.exists()) {
throw new IOException();
}
_resourceFork = true;
}
final int streamLen = (int) file.length();
final BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file), streamLen);
try {
readImpl(bis, streamLen);
} finally {
bis.close();
}
}
/**
* @param is The OpenType font stream
* @param streamLen the length of the OpenType font segment in the stream
*/
protected void read(final InputStream is, final int streamLen) throws IOException {
_pathName = "";
_fileName = "";
final InputStream bis;
if( is.markSupported() ) {
bis = is;
} else {
bis = new BufferedInputStream(is, streamLen);
}
readImpl(bis, streamLen);
}
/**
* @param is The OpenType font stream, must {@link InputStream#markSupported() support mark}!
*/
private void readImpl(final InputStream bis, final int streamLen) throws IOException {
if( !bis.markSupported() ) {
throw new IllegalArgumentException("stream of type "+bis.getClass().getName()+" doesn't support mark");
}
bis.mark(streamLen);
final DataInputStream dis = new DataInputStream(bis);
if (_resourceFork || _pathName.endsWith(".dfont")) {
// This is a Macintosh font suitcase resource
final ResourceHeader resourceHeader = new ResourceHeader(dis);
// Seek to the map offset and read the map
dis.reset();
dis.skip(resourceHeader.getMapOffset());
final ResourceMap map = new ResourceMap(dis);
// Get the 'sfnt' resources
final ResourceType resourceType = map.getResourceType("sfnt");
// Load the font data
_fonts = new OTFont[resourceType.getCount()];
for (int i = 0; i < resourceType.getCount(); i++) {
final ResourceReference resourceReference = resourceType.getReference(i);
_fonts[i] = new OTFont(this);
final int offset = resourceHeader.getDataOffset() +
resourceReference.getDataOffset() + 4;
_fonts[i].read(dis, offset, offset);
}
} else if (TTCHeader.isTTC(dis)) {
// This is a TrueType font collection
dis.reset();
_ttcHeader = new TTCHeader(dis);
_fonts = new OTFont[_ttcHeader.getDirectoryCount()];
for (int i = 0; i < _ttcHeader.getDirectoryCount(); i++) {
_fonts[i] = new OTFont(this);
_fonts[i].read(dis, _ttcHeader.getTableDirectory(i), 0);
}
} else {
// This is a standalone font file
_fonts = new OTFont[1];
_fonts[0] = new OTFont(this);
_fonts[0].read(dis, 0, 0);
}
}
}