123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- /*
- * 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.
- */
-
- /* $Id$ */
-
- package org.apache.fop.fonts.truetype;
-
- import java.io.IOException;
-
- /**
- * Reads a TrueType file or a TrueType Collection.
- * The TrueType spec can be found at the Microsoft.
- * Typography site: http://www.microsoft.com/truetype/
- */
- public class TTFFile extends OpenFont {
-
- public TTFFile() {
- this(true, false);
- }
-
- /**
- * Constructor
- * @param useKerning true if kerning data should be loaded
- * @param useAdvanced true if advanced typographic tables should be loaded
- */
- public TTFFile(boolean useKerning, boolean useAdvanced) {
- super(useKerning, useAdvanced);
- }
-
- /**
- * Read the "name" table.
- * @throws IOException In case of a I/O problem
- */
- protected void readName() throws IOException {
- seekTab(fontFile, OFTableName.NAME, 2);
- int i = fontFile.getCurrentPos();
- int n = fontFile.readTTFUShort();
- int j = fontFile.readTTFUShort() + i - 2;
- i += 2 * 2;
-
- while (n-- > 0) {
- // getLogger().debug("Iteration: " + n);
- fontFile.seekSet(i);
- final int platformID = fontFile.readTTFUShort();
- final int encodingID = fontFile.readTTFUShort();
- final int languageID = fontFile.readTTFUShort();
-
- int k = fontFile.readTTFUShort();
- int l = fontFile.readTTFUShort();
-
- if (((platformID == 1 || platformID == 3)
- && (encodingID == 0 || encodingID == 1))) {
- fontFile.seekSet(j + fontFile.readTTFUShort());
- String txt;
- if (platformID == 3) {
- txt = fontFile.readTTFString(l, encodingID);
- } else {
- txt = fontFile.readTTFString(l);
- }
-
- if (log.isDebugEnabled()) {
- log.debug(platformID + " "
- + encodingID + " "
- + languageID + " "
- + k + " " + txt);
- }
- switch (k) {
- case 0:
- if (notice.length() == 0) {
- notice = txt;
- }
- break;
- case 1: //Font Family Name
- case 16: //Preferred Family
- familyNames.add(txt);
- break;
- case 2:
- if (subFamilyName.length() == 0) {
- subFamilyName = txt;
- }
- break;
- case 4:
- if (fullName.length() == 0 || (platformID == 3 && languageID == 1033)) {
- fullName = txt;
- }
- break;
- case 6:
- if (postScriptName.length() == 0) {
- postScriptName = txt;
- }
- break;
- default:
- break;
- }
- }
- i += 6 * 2;
- }
- }
-
- /**
- * Read the "glyf" table to find the bounding boxes.
- * @throws IOException In case of a I/O problem
- */
- private void readGlyf() throws IOException {
- OFDirTabEntry dirTab = dirTabs.get(OFTableName.GLYF);
- if (dirTab == null) {
- throw new IOException("glyf table not found, cannot continue");
- }
- for (int i = 0; i < (numberOfGlyphs - 1); i++) {
- if (mtxTab[i].getOffset() != mtxTab[i + 1].getOffset()) {
- fontFile.seekSet(dirTab.getOffset() + mtxTab[i].getOffset());
- fontFile.skip(2);
- final int[] bbox = {
- fontFile.readTTFShort(),
- fontFile.readTTFShort(),
- fontFile.readTTFShort(),
- fontFile.readTTFShort()};
- mtxTab[i].setBoundingBox(bbox);
- } else {
- mtxTab[i].setBoundingBox(mtxTab[0].getBoundingBox());
- }
- }
-
- long n = (dirTabs.get(OFTableName.GLYF)).getOffset();
- for (int i = 0; i < numberOfGlyphs; i++) {
- if ((i + 1) >= mtxTab.length
- || mtxTab[i].getOffset() != mtxTab[i + 1].getOffset()) {
- fontFile.seekSet(n + mtxTab[i].getOffset());
- fontFile.skip(2);
- final int[] bbox = {
- fontFile.readTTFShort(),
- fontFile.readTTFShort(),
- fontFile.readTTFShort(),
- fontFile.readTTFShort()};
- mtxTab[i].setBoundingBox(bbox);
- } else {
- /**@todo Verify that this is correct, looks like a copy/paste bug (jm)*/
- final int bbox0 = mtxTab[0].getBoundingBox()[0];
- final int[] bbox = {bbox0, bbox0, bbox0, bbox0};
- mtxTab[i].setBoundingBox(bbox);
- /* Original code
- mtxTab[i].bbox[0] = mtxTab[0].bbox[0];
- mtxTab[i].bbox[1] = mtxTab[0].bbox[0];
- mtxTab[i].bbox[2] = mtxTab[0].bbox[0];
- mtxTab[i].bbox[3] = mtxTab[0].bbox[0]; */
- }
- if (log.isTraceEnabled()) {
- log.trace(mtxTab[i].toString(this));
- }
- }
- }
-
- @Override
- protected void updateBBoxAndOffset() throws IOException {
- readIndexToLocation();
- readGlyf();
- }
-
- /**
- * Read the "loca" table.
- * @throws IOException In case of a I/O problem
- */
- protected final void readIndexToLocation()
- throws IOException {
- if (!seekTab(fontFile, OFTableName.LOCA, 0)) {
- throw new IOException("'loca' table not found, happens when the font file doesn't"
- + " contain TrueType outlines (trying to read an OpenType CFF font maybe?)");
- }
- for (int i = 0; i < numberOfGlyphs; i++) {
- mtxTab[i].setOffset(locaFormat == 1 ? fontFile.readTTFULong()
- : (fontFile.readTTFUShort() << 1));
- }
- lastLoca = (locaFormat == 1 ? fontFile.readTTFULong()
- : (fontFile.readTTFUShort() << 1));
- }
-
- @Override
- protected void initializeFont(FontFileReader in) throws IOException {
- fontFile = in;
- }
- }
|