/* 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(); } }