/* FontInfo.java
* =========================================================================
* This file is originally part of the JMathTeX Library - http://jmathtex.sourceforge.net
*
* Copyright (C) 2004-2007 Universiteit Gent
* Copyright (C) 2009 DENIZET Calixte
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* 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
* General Public License for more details.
*
* A copy of the GNU General Public License can be found in the file
* LICENSE.txt provided with the source distribution of this program (see
* the META-INF directory in the source jar). This license can also be
* found on the GNU website at http://www.gnu.org/licenses/gpl.html.
*
* If you did not receive a copy of the GNU General Public License along
* with this program, contact the lead developer, or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* Linking this library statically or dynamically with other modules
* is making a combined work based on this library. Thus, the terms
* and conditions of the GNU General Public License cover the whole
* combination.
*
* As a special exception, the copyright holders of this library give you
* permission to link this library with independent modules to produce
* an executable, regardless of the license terms of these independent
* modules, and to copy and distribute the resulting executable under terms
* of your choice, provided that you also meet, for each linked independent
* module, the terms and conditions of the license of that module.
* An independent module is a module which is not derived from or based
* on this library. If you modify this library, you may extend this exception
* to your version of the library, but you are not obliged to do so.
* If you do not wish to do so, delete this exception statement from your
* version.
*
*/
package com.himamis.retex.renderer.share;
import java.util.HashMap;
import java.util.Map;
import com.himamis.retex.renderer.share.platform.font.Font;
/**
* Contains all the font information for 1 font.
*/
public class FontInfo {
/**
* Maximum number of character codes in a TeX font.
*/
public static final int NUMBER_OF_CHAR_CODES = 256;
private static Map<Integer, FontInfo> fonts = new HashMap<Integer, FontInfo>();
private class CharCouple {
private final char left, right;
CharCouple(char l, char r) {
left = l;
right = r;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof CharCouple)) {
return false;
}
CharCouple ligo = (CharCouple) o;
return left == ligo.left && right == ligo.right;
}
@Override
public int hashCode() {
return (left + right) % 128;
}
}
// ID
private final int fontId;
// font
private Font font;
private final Object base;
private final String path;
private final Map<CharCouple, Character> lig = new HashMap<CharCouple, Character>();
private final Map<CharCouple, Double> kern = new HashMap<CharCouple, Double>();
private double[][] metrics;
private CharFont[] nextLarger;
private int[][] extensions;
private HashMap<Character, Character> unicode = null;
// skew character of the font (used for positioning accents)
private char skewChar = (char) -1;
// general parameters for this font
private final double xHeight;
private final double space;
private final double quad;
private int boldId;
private int romanId;
private int ssId;
private int ttId;
private int itId;
protected final String boldVersion;
protected final String romanVersion;
protected final String ssVersion;
protected final String ttVersion;
protected final String itVersion;
public FontInfo(int fontId, Object base, String path, int unicode,
double xHeight,
double space, double quad, String boldVersion, String romanVersion, String ssVersion,
String ttVersion, String itVersion) {
this.fontId = fontId;
this.base = base;
this.path = path;
this.xHeight = xHeight;
this.space = space;
this.quad = quad;
this.boldVersion = boldVersion;
this.romanVersion = romanVersion;
this.ssVersion = ssVersion;
this.ttVersion = ttVersion;
this.itVersion = itVersion;
int num = NUMBER_OF_CHAR_CODES;
if (unicode != 0) {
this.unicode = new HashMap<Character, Character>(unicode);
num = unicode;
}
metrics = new double[num][];
nextLarger = new CharFont[num];
extensions = new int[num][];
fonts.put(fontId, this);
}
/**
*
* @param left left character
* @param right right character
* @param k kern value
*/
public void addKern(char left, char right, double k) {
kern.put(new CharCouple(left, right), new Double(k));
}
/**
* @param left left character
* @param right right character
* @param ligChar ligature to replace left and right character
*/
public void addLigature(char left, char right, char ligChar) {
lig.put(new CharCouple(left, right), new Character(ligChar));
}
public int[] getExtension(char ch) {
if (unicode == null) {
return extensions[ch];
}
return extensions[unicode.get(ch)];
}
public double getKern(char left, char right, double factor) {
Object obj = kern.get(new CharCouple(left, right));
if (obj == null) {
return 0;
}
return ((Double) obj).doubleValue() * factor;
}
public CharFont getLigature(char left, char right) {
Object obj = lig.get(new CharCouple(left, right));
if (obj == null) {
return null;
}
return new CharFont(((Character) obj).charValue(), fontId);
}
public double[] getMetrics(char c) {
if (unicode == null) {
return metrics[c];
}
return metrics[unicode.get(c)];
}
public CharFont getNextLarger(char ch) {
if (unicode == null) {
return nextLarger[ch];
}
return nextLarger[unicode.get(ch)];
}
public double getQuad(double factor) {
return quad * factor;
}
/**
* @return the skew character of the font (for the correct positioning of accents)
*/
public char getSkewChar() {
return skewChar;
}
public double getSpace(double factor) {
return space * factor;
}
public double getXHeight(double factor) {
return xHeight * factor;
}
public boolean hasSpace() {
return space > TeXFormula.PREC;
}
public void setExtension(char ch, int[] ext) {
if (unicode == null) {
extensions[ch] = ext;
} else if (!unicode.containsKey(ch)) {
char s = (char) unicode.size();
unicode.put(ch, s);
extensions[s] = ext;
} else {
extensions[unicode.get(ch)] = ext;
}
}
public void setMetrics(char c, double[] arr) {
if (unicode == null) {
metrics[c] = arr;
} else if (!unicode.containsKey(c)) {
char s = (char) unicode.size();
unicode.put(c, s);
metrics[s] = arr;
} else {
metrics[unicode.get(c)] = arr;
}
}
public void setNextLarger(char ch, char larger, int fontLarger) {
if (unicode == null) {
nextLarger[ch] = new CharFont(larger, fontLarger);
} else if (!unicode.containsKey(ch)) {
char s = (char) unicode.size();
unicode.put(ch, s);
nextLarger[s] = new CharFont(larger, fontLarger);
} else {
nextLarger[unicode.get(ch)] = new CharFont(larger, fontLarger);
}
}
public void setSkewChar(char c) {
skewChar = c;
}
public int getId() {
return fontId;
}
public int getBoldId() {
return boldId;
}
public int getRomanId() {
return romanId;
}
public int getTtId() {
return ttId;
}
public int getItId() {
return itId;
}
public int getSsId() {
return ssId;
}
public void setSsId(int id) {
ssId = id == -1 ? fontId : id;
}
public void setTtId(int id) {
ttId = id == -1 ? fontId : id;
}
public void setItId(int id) {
itId = id == -1 ? fontId : id;
}
public void setRomanId(int id) {
romanId = id == -1 ? fontId : id;
}
public void setBoldId(int id) {
boldId = id == -1 ? fontId : id;
}
public Font getFont() {
if (font == null) {
if (base == null) {
font = DefaultTeXFontParser.createFont(path);
} else {
font = DefaultTeXFontParser.createFont(base, path);
}
}
return font;
}
public static Font getFont(int id) {
return fonts.get(id).getFont();
}
}