com.sun.pdfview.font.ttf.PostTable Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pdf-renderer Show documentation
Show all versions of pdf-renderer Show documentation
PDF renderer implementation supporting the subset of PDF 1.4 specification.
The newest version!
/*
* $Id: PostTable.java,v 1.2 2007-12-20 18:33:31 rbair Exp $
*
* Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
* Santa Clara, California 95054, U.S.A. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package com.sun.pdfview.font.ttf;
import java.nio.ByteBuffer;
/**
* Model the TrueType Post table
*
* @author jkaplan
*/
public class PostTable extends TrueTypeTable {
/** Holds value of property format. */
private int format;
/** Holds value of property italicAngle. */
private int italicAngle;
/** Holds value of property underlinePosition. */
private short underlinePosition;
/** Holds value of property underlineThickness. */
private short underlineThickness;
/** Holds value of property isFixedPitch. */
private short isFixedPitch;
/** Holds value of property minMemType42. */
private int minMemType42;
/** Holds value of property maxMemType42. */
private int maxMemType42;
/** Holds value of property minMemType1. */
private int minMemType1;
/** Holds value of property maxMemType1. */
private int maxMemType1;
/** A map which character values to names and vice versa */
private PostMap nameMap;
/** Creates a new instance of PostTable */
protected PostTable() {
super (TrueTypeTable.POST_TABLE);
nameMap = new PostMap();
}
/**
* Map a character name to a glyphNameIndex
*/
public short getGlyphNameIndex(String name) {
return nameMap.getCharIndex(name);
}
/**
* Map a character code to a glyphIndex name
*/
public String getGlyphName(char c) {
return nameMap.getCharName(c);
}
/** get the data in this map as a ByteBuffer */
public ByteBuffer getData() {
int size = getLength();
ByteBuffer buf = ByteBuffer.allocate(size);
// write the header
buf.putInt(getFormat());
buf.putInt(getItalicAngle());
buf.putShort(getUnderlinePosition());
buf.putShort(getUnderlineThickness());
buf.putShort(getIsFixedPitch());
buf.putShort((short) 0);
buf.putInt(getMinMemType42());
buf.putInt(getMaxMemType42());
buf.putInt(getMinMemType1());
buf.putInt(getMaxMemType1());
// now write the table
buf.put(nameMap.getData());
// reset the start pointer
buf.flip();
return buf;
}
/** Initialize this structure from a ByteBuffer */
public void setData(ByteBuffer data) {
setFormat(data.getInt());
setItalicAngle(data.getInt());
setUnderlinePosition(data.getShort());
setUnderlineThickness(data.getShort());
setIsFixedPitch(data.getShort());
data.getShort();
setMinMemType42(data.getInt());
setMaxMemType42(data.getInt());
setMinMemType1(data.getInt());
setMaxMemType1(data.getInt());
// create the map, based on the type
switch (format) {
case 0x10000:
nameMap = new PostMapFormat0();
break;
case 0x20000:
nameMap = new PostMapFormat2();
break;
case 0x30000:
// empty post map.
nameMap = new PostMap();
break;
default:
nameMap = new PostMap();
System.out.println("Unknown post map type: " +
Integer.toHexString(format));
break;
}
// fill in the data in the map
nameMap.setData(data);
}
/**
* Get the length of this table
*/
public int getLength() {
int size = 32;
if (nameMap != null) {
size += nameMap.getLength();
}
return size;
}
/** Getter for property format.
* @return Value of property format.
*
*/
public int getFormat() {
return this.format;
}
/** Setter for property format.
* @param format New value of property format.
*
*/
public void setFormat(int format) {
this.format = format;
}
/** Getter for property italicAngle.
* @return Value of property italicAngle.
*
*/
public int getItalicAngle() {
return this.italicAngle;
}
/** Setter for property italicAngle.
* @param italicAngle New value of property italicAngle.
*
*/
public void setItalicAngle(int italicAngle) {
this.italicAngle = italicAngle;
}
/** Getter for property underlinePosition.
* @return Value of property underlinePosition.
*
*/
public short getUnderlinePosition() {
return this.underlinePosition;
}
/** Setter for property underlinePosition.
* @param underlinePosition New value of property underlinePosition.
*
*/
public void setUnderlinePosition(short underlinePosition) {
this.underlinePosition = underlinePosition;
}
/** Getter for property underlineThickness.
* @return Value of property underlineThickness.
*
*/
public short getUnderlineThickness() {
return this.underlineThickness;
}
/** Setter for property underlineThickness.
* @param underlineThickness New value of property underlineThickness.
*
*/
public void setUnderlineThickness(short underlineThickness) {
this.underlineThickness = underlineThickness;
}
/** Getter for property isFixedPitch.
* @return Value of property isFixedPitch.
*
*/
public short getIsFixedPitch() {
return this.isFixedPitch;
}
/** Setter for property isFixedPitch.
* @param isFixedPitch New value of property isFixedPitch.
*
*/
public void setIsFixedPitch(short isFixedPitch) {
this.isFixedPitch = isFixedPitch;
}
/** Getter for property minMemType42.
* @return Value of property minMemType42.
*
*/
public int getMinMemType42() {
return this.minMemType42;
}
/** Setter for property minMemType42.
* @param minMemType42 New value of property minMemType42.
*
*/
public void setMinMemType42(int minMemType42) {
this.minMemType42 = minMemType42;
}
/** Getter for property maxMemType42.
* @return Value of property maxMemType42.
*
*/
public int getMaxMemType42() {
return this.maxMemType42;
}
/** Setter for property maxMemType42.
* @param maxMemType42 New value of property maxMemType42.
*
*/
public void setMaxMemType42(int maxMemType42) {
this.maxMemType42 = maxMemType42;
}
/** Getter for property minMemType1.
* @return Value of property minMemType1.
*
*/
public int getMinMemType1() {
return this.minMemType1;
}
/** Setter for property minMemType1.
* @param minMemType1 New value of property minMemType1.
*
*/
public void setMinMemType1(int minMemType1) {
this.minMemType1 = minMemType1;
}
/** Getter for property maxMemType1.
* @return Value of property maxMemType1.
*
*/
public int getMaxMemType1() {
return this.maxMemType1;
}
/** Setter for property maxMemType1.
* @param maxMemType1 New value of property maxMemType1.
*
*/
public void setMaxMemType1(int maxMemType1) {
this.maxMemType1 = maxMemType1;
}
/** An empty post map */
class PostMap {
/** map a name to a character index */
short getCharIndex(String charName) {
return (short) 0;
}
/** name a character index to a name */
String getCharName(char charIndex) {
return null;
}
/** get the length of the data in this map */
int getLength() {
return 0;
}
/** get the data in this map as a ByteBuffer */
ByteBuffer getData() {
return ByteBuffer.allocate(0);
}
/** set the data in this map from a ByteBuffer */
void setData(ByteBuffer data) {
// do nothing
return;
}
}
/** A Format 0 post map */
class PostMapFormat0 extends PostMap {
/** the glyph names in standard Macintosh ordering */
protected final String stdNames[] = {
/* 0 */ ".notdef", ".null", "nonmarkingreturn", "space", "exclam", "quotedbl", "numbersign", "dollar",
/* 8 */ "percent", "ampersand", "quotesingle", "parenleft", "parenright", "asterisk", "plus", "comma",
/* 16 */ "hyphen", "period", "slash", "zero", "one", "two", "three", "four",
/* 24 */ "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less",
/* 32 */ "equal", "greater", "question", "at", "A", "B", "C", "D",
/* 40 */ "E", "F", "G", "H", "I", "J", "K", "L",
/* 48 */ "M", "N", "O", "P", "Q", "R", "S", "T",
/* 56 */ "U", "V", "W", "X", "Y", "Z", "bracketleft", "ackslash",
/* 64 */ "bracketright", "asciicircum", "underscore", "grave", "a", "b", "c", "d",
/* 72 */ "e", "f", "g", "h", "i", "j", "k", "l",
/* 80 */ "m", "n", "o", "p", "q", "r", "s", "t",
/* 88 */ "u", "v", "w", "x", "y", "z", "braceleft", "bar",
/* 96 */ "braceright", "asciitilde", "Adieresis", "Aring", "Ccedilla", "Eacute", "Ntilde", "Odieresis",
/* 104 */ "Udieresis", "aacute", "agrave", "acircumflex", "adieresis", "atilde", "aring", "ccedilla",
/* 112 */ "eacute", "egrave", "ecircumflex", "edieresis", "iacute", "igrave", "icircumflex", "idieresis",
/* 120 */ "ntilde", "oacute", "ograve", "ocircumflex", "odieresis", "otilde", "uacute", "ugrave",
/* 128 */ "ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling", "section", "bullet",
/* 136 */ "paragraph", "germandbls", "registered", "copyright", "trademark", "acute", "dieresis", "notequal",
/* 144 */ "AE", "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", "yen", "mu",
/* 152 */ "partialdiff", "summation", "product", "pi", "integral", "ordfeminine", "ordmasculine", "Omega",
/* 160 */ "ae", "oslash", "questiondown", "exclamdown", "logicalnot", "radical", "florin", "approxequal",
/* 168 */ "Delta", "guillemotleft", "guillemotright", "ellipsis", "nonbreakingspace", "Agrave", "Atilde", "Otilde",
/* 176 */ "OE", "oe", "endash", "emdash", "quotedblleft", "quotedblright", "quoteleft", "quoteright",
/* 184 */ "divide", "lozenge", "ydieresis", "Ydieresis", "fraction", "currency", "guilsinglleft", "guilsinglright",
/* 192 */ "fi", "fl", "daggerdbl", "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex",
/* 200 */ "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave",
/* 208 */ "Oacute", "Ocircumflex", "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", "dotlessi",
/* 216 */ "circumflex", "tilde", "macron", "breve", "dotaccent", "ring", "cedilla", "hungarumlaut",
/* 224 */ "ogonek", "caron", "Lslash", "lslash", "Scaron", "scaron", "Zcaron", "zcaron",
/* 232 */ "brokenbar", "Eth", "eth", "Yacute", "yacute", "Thorn", "thorn", "minus",
/* 240 */ "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf", "onequarter", "threequarters", "franc",
/* 248 */ "Gbreve", "gbreve", "Idotaccent", "Scedilla", "scedilla", "Cacute", "cacute", "Ccaron",
/* 256 */ "ccaron", "dcroat"
};
/** map a name to a character index */
short getCharIndex(String charName) {
for (int i = 0; i < stdNames.length; i++) {
if (charName.equals(stdNames[i])) {
return (short) i;
}
}
return (short) 0;
}
/** name a character index to a name */
String getCharName(char charIndex) {
return stdNames[charIndex];
}
/** get the length of the data in this map */
int getLength() {
return 0;
}
/** get the data in this map as a ByteBuffer */
ByteBuffer getData() {
return ByteBuffer.allocate(0);
}
/** set the data in this map from a ByteBuffer */
void setData(ByteBuffer data) {
// do nothing
return;
}
}
/** an extension to handle format 2 post maps */
class PostMapFormat2 extends PostMapFormat0 {
/** the glyph name index */
short[] glyphNameIndex;
/** the glyph names */
String[] glyphNames;
/** Map a character name to an index */
short getCharIndex(String charName) {
// find the index of this character name
short idx = -1;
// first try the local names map
for (int i = 0; i < glyphNames.length; i++) {
if (charName.equals(glyphNames[i])) {
// this is the value from the glyph name index
idx = (short) (stdNames.length + i);
break;
}
}
// if that doesn't work, try the standard names
if (idx == -1) {
idx = super.getCharIndex(charName);
}
// now get the entry in the index
for (int c = 0; c < glyphNameIndex.length; c++) {
if (glyphNameIndex[c] == idx) {
return (short) c;
}
}
// not found
return (short) 0;
}
/** Map an index to a character name */
String getCharName(char charIndex) {
if (charIndex >= stdNames.length) {
return glyphNames[charIndex - stdNames.length];
}
return super.getCharName(charIndex);
}
/** get the length of this class's data */
int getLength() {
// the size of the header plus the table of mappings
int size = 2 + (2 * glyphNameIndex.length);
// the size of each string -- note the extra byte for a pascal
// string
for (int i = 0; i < glyphNames.length; i++) {
size += glyphNames[i].length() + 1;
}
return size;
}
/** get the data in this map as a byte array */
ByteBuffer getData() {
ByteBuffer buf = ByteBuffer.allocate(getLength());
// write the number of glyphs
buf.putShort((short) glyphNameIndex.length);
// write the name indices
for (int i = 0; i < glyphNameIndex.length; i++) {
buf.putShort(glyphNameIndex[i]);
}
// write the names as pascal strings
for (int i = 0; i < glyphNames.length; i++) {
buf.put((byte) glyphNames[i].length());
buf.put(glyphNames[i].getBytes());
}
// reset the start pointer
buf.flip();
return buf;
}
/** set the contents of this map from a ByteBuffer */
void setData(ByteBuffer data) {
short numGlyphs = data.getShort();
glyphNameIndex = new short[numGlyphs];
// the highest glyph index seen so far
int maxGlyph = 257;
for (int i = 0; i < numGlyphs; i++) {
glyphNameIndex[i] = data.getShort();
// see if this is the highest glyph
if (glyphNameIndex[i] > maxGlyph) {
maxGlyph = glyphNameIndex[i];
}
}
// subtract off the default glyphs
maxGlyph -= 257;
// read in any additional names
glyphNames = new String[maxGlyph];
// read each name from a pascal string
// the length is stored in the first byte, followed by
// the data
for (int i = 0; i < maxGlyph; i++) {
// size in the first byte
byte size = data.get();
// then the data
byte[] stringData = new byte[size];
data.get(stringData);
glyphNames[i] = new String(stringData);
}
}
}
}