diff options
author | yehh <yehh@google.com> | 2012-08-15 21:58:18 +0000 |
---|---|---|
committer | yehh <yehh@google.com> | 2012-08-15 21:58:18 +0000 |
commit | fe684ca7642f00019417272f69b6898d255272f4 (patch) | |
tree | 0a303fe3de025a93234ed2a5f5d2629ab160b170 | |
parent | 4a07f45e822ecf6f7a05eee07a6617e80ca280b2 (diff) | |
download | sfntly-fe684ca7642f00019417272f69b6898d255272f4.tar.gz |
Merging Brian's font tool into Han-Wen's
CL @ http://codereview.appspot.com/6462061/
6 files changed, 205 insertions, 513 deletions
diff --git a/java/src/com/google/typography/font/sfntly/math/Fixed1616.java b/java/src/com/google/typography/font/sfntly/math/Fixed1616.java index 5157793..70b9499 100644 --- a/java/src/com/google/typography/font/sfntly/math/Fixed1616.java +++ b/java/src/com/google/typography/font/sfntly/math/Fixed1616.java @@ -33,6 +33,14 @@ public final class Fixed1616 { public static int fixed(int integral, int fractional) { return ((integral & 0xffff) << 16) | (fractional & 0xffff); } + + /** + * @param fixed the number to convert + * @return a double representing the 16-16 floating point number + */ + public static double doubleValue(int fixed) { + return fixed / 65536.0; // shift the decimal 16 bits + } public static String toString(int fixed) { StringBuilder sb = new StringBuilder(); diff --git a/java/src/com/google/typography/font/tools/fontinfo/FontInfo.java b/java/src/com/google/typography/font/tools/fontinfo/FontInfo.java index 18087f5..ba81b67 100644 --- a/java/src/com/google/typography/font/tools/fontinfo/FontInfo.java +++ b/java/src/com/google/typography/font/tools/fontinfo/FontInfo.java @@ -8,6 +8,7 @@ import com.google.typography.font.sfntly.Font.UnicodeEncodingId; import com.google.typography.font.sfntly.Font.WindowsEncodingId; import com.google.typography.font.sfntly.Tag; import com.google.typography.font.sfntly.Font.PlatformId; +import com.google.typography.font.sfntly.math.Fixed1616; import com.google.typography.font.sfntly.table.Table; import com.google.typography.font.sfntly.table.core.CMap; import com.google.typography.font.sfntly.table.core.CMapTable; @@ -34,6 +35,7 @@ import com.ibm.icu.lang.UScript; import com.ibm.icu.text.UnicodeSet; import java.text.DecimalFormat; +import java.text.NumberFormat; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; @@ -45,11 +47,9 @@ import java.util.TreeSet; /** * Class of static functions that return information about a given font * - * @author Han-Wen Yeh + * @author Brian Stell, Han-Wen Yeh * */ -// TODO Incorporate Brian's functions into this class to make a more centralized -// font information tool // TODO Make abstract FontInfo class with nonstatic functions and subclass this // as TrueTypeFontInfo public class FontInfo { @@ -57,6 +57,19 @@ public class FontInfo { private static final DecimalFormat twoDecimalPlaces = new DecimalFormat("#.##"); /** + * @param font + * the source font + * @return the sfnt version of the font + */ + public static String sfntVersion(Font font) { + double version = Fixed1616.doubleValue(font.sfntVersion()); + NumberFormat numberFormatter = NumberFormat.getInstance(); + numberFormatter.setMinimumFractionDigits(2); + numberFormatter.setGroupingUsed(false); + return numberFormatter.format(version); + } + + /** * Gets a list of information regarding various dimensions about the given * font from the head, hhea, and OS/2 font tables * @@ -71,9 +84,9 @@ public class FontInfo { table.setAlignment(Arrays.asList(displayAlignment)); // Retrieve necessary tables - FontHeaderTable headTable = (FontHeaderTable) getTable(font, Tag.head); - HorizontalHeaderTable hheaTable = (HorizontalHeaderTable) getTable(font, Tag.hhea); - OS2Table os2Table = (OS2Table) getTable(font, Tag.OS_2); + FontHeaderTable headTable = (FontHeaderTable) FontUtils.getTable(font, Tag.head); + HorizontalHeaderTable hheaTable = (HorizontalHeaderTable) FontUtils.getTable(font, Tag.hhea); + OS2Table os2Table = (OS2Table) FontUtils.getTable(font, Tag.OS_2); table.add(Arrays.asList( new String[] { "Units per em", String.format("%d", headTable.unitsPerEm()) })); @@ -165,7 +178,7 @@ public class FontInfo { DataDisplayTable table = new DataDisplayTable(Arrays.asList(header)); table.setAlignment(Arrays.asList(displayAlignment)); - NameTable nameTable = (NameTable) getTable(font, Tag.name); + NameTable nameTable = (NameTable) FontUtils.getTable(font, Tag.name); for (NameEntry entry : nameTable) { String eidEntry = ""; // Platform-specific encoding @@ -214,7 +227,7 @@ public class FontInfo { table.setAlignment(Arrays.asList(displayAlignment)); // Add information about each individual cmap in the table - CMapTable cmapTable = getCMapTable(font); + CMapTable cmapTable = FontUtils.getCMapTable(font); for (CMap cmap : cmapTable) { String[] data = { String.format("%d", cmap.platformId()), String.format("%d", cmap.encodingId()), String.format("%d", cmap.format()) }; @@ -235,7 +248,7 @@ public class FontInfo { */ public static int numChars(Font font) { int numChars = 0; - CMap cmap = getUCSCMap(font); + CMap cmap = FontUtils.getUCSCMap(font); // Find the number of characters that point to a valid glyph for (int charId : cmap) { @@ -266,12 +279,12 @@ public class FontInfo { table.setAlignment(Arrays.asList(displayAlignment)); // Iterate through all code points - CMap cmap = getUCSCMap(font); + CMap cmap = FontUtils.getUCSCMap(font); for (int charId : cmap) { int glyphId = cmap.glyphId(charId); if (glyphId != CMapTable.NOTDEF) { - String[] data = { getFormattedCodePointString(charId), String.format("%d", glyphId), - UCharacter.getExtendedName(charId) }; + String[] data = { FontUtils.getFormattedCodePointString(charId), + String.format("%d", glyphId), UCharacter.getExtendedName(charId) }; table.add(Arrays.asList(data)); } } @@ -299,7 +312,7 @@ public class FontInfo { table.setAlignment(Arrays.asList(displayAlignment)); // Iterate through each block to check for coverage - CMap cmap = getUCSCMap(font); + CMap cmap = FontUtils.getUCSCMap(font); int totalCount = 0; for (int i = 0; i < UnicodeBlockData.numBlocks(); i++) { String block = UnicodeBlockData.getBlockName(i); @@ -355,7 +368,7 @@ public class FontInfo { HashMap<Integer, Integer> coveredScripts = new HashMap<Integer, Integer>(); // Add to script count for the script each code point belongs to - CMap cmap = getUCSCMap(font); + CMap cmap = FontUtils.getUCSCMap(font); for (int charId : cmap) { if (cmap.glyphId(charId) != CMapTable.NOTDEF) { int scriptCode = UScript.getScript(charId); @@ -408,7 +421,7 @@ public class FontInfo { HashMap<Integer, UnicodeSet> coveredScripts = new HashMap<Integer, UnicodeSet>(); // Iterate through each set - CMap cmap = getUCSCMap(font); + CMap cmap = FontUtils.getUCSCMap(font); for (int charId : cmap) { if (cmap.glyphId(charId) != CMapTable.NOTDEF) { int scriptCode = UScript.getScript(charId); @@ -441,7 +454,8 @@ public class FontInfo { for (String charStr : uSet) { int codePoint = UCharacter.codePointAt(charStr, 0); table.add(Arrays.asList(new String[] { String.format("%s", UScript.getName(scriptCode)), - getFormattedCodePointString(codePoint), UCharacter.getExtendedName(codePoint) })); + FontUtils.getFormattedCodePointString(codePoint), + UCharacter.getExtendedName(codePoint) })); } } @@ -458,7 +472,7 @@ public class FontInfo { * if font does not contain a valid glyf table */ public static int numGlyphs(Font font) { - return ((MaximumProfileTable) getTable(font, Tag.maxp)).numGlyphs(); + return ((MaximumProfileTable) FontUtils.getTable(font, Tag.maxp)).numGlyphs(); } /** @@ -476,8 +490,8 @@ public class FontInfo { DataDisplayTable table = new DataDisplayTable(Arrays.asList(header)); table.setAlignment(Arrays.asList(displayAlignment)); - LocaTable locaTable = getLocaTable(font); - GlyphTable glyfTable = getGlyphTable(font); + LocaTable locaTable = FontUtils.getLocaTable(font); + GlyphTable glyfTable = FontUtils.getGlyphTable(font); // Initialise boundaries int xMin = Integer.MAX_VALUE; @@ -521,8 +535,8 @@ public class FontInfo { public static String hintingSize(Font font) { int instrSize = 0; - LocaTable locaTable = getLocaTable(font); - GlyphTable glyfTable = getGlyphTable(font); + LocaTable locaTable = FontUtils.getLocaTable(font); + GlyphTable glyfTable = FontUtils.getGlyphTable(font); // Get hinting information from each glyph for (int i = 0; i < locaTable.numGlyphs(); i++) { @@ -551,8 +565,8 @@ public class FontInfo { DataDisplayTable table = new DataDisplayTable(Arrays.asList(header)); table.setAlignment(Arrays.asList(displayAlignment)); - LocaTable locaTable = getLocaTable(font); - GlyphTable glyfTable = getGlyphTable(font); + LocaTable locaTable = FontUtils.getLocaTable(font); + GlyphTable glyfTable = FontUtils.getGlyphTable(font); // Add subglyphs of all composite glyphs to hashmap for (int i = 0; i < locaTable.numGlyphs(); i++) { @@ -598,7 +612,7 @@ public class FontInfo { // Get a set of all mapped glyph IDs Set<Integer> mappedGlyphs = new HashSet<Integer>(); - CMapTable cmapTable = getCMapTable(font); + CMapTable cmapTable = FontUtils.getCMapTable(font); for (CMap cmap : cmapTable) { for (Integer codePoint : cmap) { mappedGlyphs.add(cmap.glyphId(codePoint)); @@ -606,7 +620,7 @@ public class FontInfo { } // Iterate through all glyph IDs and check if in the set - LocaTable locaTable = getLocaTable(font); + LocaTable locaTable = FontUtils.getLocaTable(font); for (int i = 0; i < locaTable.numGlyphs(); i++) { if (!mappedGlyphs.contains(i)) { table.add(Arrays.asList(new String[] { String.format("%d", i) })); @@ -628,111 +642,7 @@ public class FontInfo { // TODO Find number of code points that use simple glyphs and number of code // points that use composite glyphs (and provide a list of code points for // each one) - // public static int numSimpleGlyphs(Font font) {} // public static int listSimpleGlyphs(Font font) {} - // public static int numCompositeglyphs(Font font) {} // public static int listCompositeGlyphs(Font font) {} - /** - * Gets the table with the specified tag for the given font - * - * @param font - * the source font - * @param tag - * the tag for the table to return - * @return the specified table for the given font - * @throws UnsupportedOperationException - * if the font does not contain the table with the specified tag - * @see Tag - */ - private static Table getTable(Font font, int tag) { - Table table = font.getTable(tag); - if (table == null) { - throw new RuntimeException("Font has no " + Tag.stringValue(tag) + " table"); - } - return table; - } - - /** - * Gets the cmap table for the given font - * - * @param font - * the source font - * @return the cmap table for the given font - * @throws UnsupportedOperationException - * if the font does not contain a valid cmap table - */ - private static CMapTable getCMapTable(Font font) { - return (CMapTable) getTable(font, Tag.cmap); - } - - /** - * Gets either a UCS4 or UCS2 cmap, if available - * - * @param font - * the source font - * @return the UCS4 or UCS2 cmap - * @throws UnsupportedOperationException - * if font does not contain a UCS-4 or UCS-2 cmap - */ - private static CMap getUCSCMap(Font font) { - CMapTable cmapTable = getCMapTable(font); - - // Obtain the UCS-4 cmap. If it doesn't exist, then obtain the UCS-2 cmap - CMap cmap = null; - cmap = cmapTable.cmap( - Font.PlatformId.Windows.value(), Font.WindowsEncodingId.UnicodeUCS4.value()); - if (cmap == null) { - cmap = cmapTable.cmap( - Font.PlatformId.Windows.value(), Font.WindowsEncodingId.UnicodeUCS2.value()); - } - if (cmap == null) { - throw new UnsupportedOperationException("Font has no UCS-4 or UCS-2 cmap"); - } - - return cmap; - } - - /** - * Gets the loca table for the given font - * - * @param font - * the source font - * @return the loca table for the given font - * @throws UnsupportedOperationException - * if the font does not contain a valid loca table - */ - private static LocaTable getLocaTable(Font font) { - return (LocaTable) getTable(font, Tag.loca); - } - - /** - * Gets the glyph table for the given font - * - * @param font - * the source font - * @return the glyph table for the given font - * @throws UnsupportedOperationException - * if the font does not contain a valid glyph table - */ - private static GlyphTable getGlyphTable(Font font) { - return (GlyphTable) getTable(font, Tag.glyf); - } - - /** - * Gets a string version of the code point formatted as "U+hhhh" or "U+hhhhhh" - * - * @param codePoint - * the code point to format - * @return a formatted version of the code point as a string - */ - private static String getFormattedCodePointString(int codePoint) { - if (UCharacter.isValidCodePoint(codePoint)) { - if (UCharacter.isBMP(codePoint)) { - return String.format("U+%04X", codePoint); - } - return String.format("U+%06X", codePoint); - } - throw new IllegalArgumentException("Invalid code point " + codePoint); - } } diff --git a/java/src/com/google/typography/font/tools/fontinfo/FontInfoMain.java b/java/src/com/google/typography/font/tools/fontinfo/FontInfoMain.java index b51bb99..3ca412d 100644 --- a/java/src/com/google/typography/font/tools/fontinfo/FontInfoMain.java +++ b/java/src/com/google/typography/font/tools/fontinfo/FontInfoMain.java @@ -3,19 +3,16 @@ package com.google.typography.font.tools.fontinfo; import com.google.typography.font.sfntly.Font; -import com.google.typography.font.sfntly.FontFactory; import com.beust.jcommander.JCommander; import com.beust.jcommander.ParameterException; -import java.io.FileInputStream; import java.io.IOException; -import java.io.InputStream; /** * This is the main class for the command-line version of the font info tool * - * @author yehh@google.com (Han-Wen Yeh) + * @author Han-Wen Yeh * */ public class FontInfoMain { @@ -57,7 +54,7 @@ public class FontInfoMain { // Load font Font[] fonts = null; try { - fonts = getFont(fileName); + fonts = FontUtils.getFonts(fileName); } catch (IOException e) { System.out.println("Unable to load font " + fileName); return; @@ -73,6 +70,8 @@ public class FontInfoMain { // Print general information if (options.general || options.all) { if (options.csv) { + System.out.println(String.format("sfnt version: %s", FontInfo.sfntVersion(font))); + System.out.println(); System.out.println("Font Tables"); System.out.println( prependDataAndBuildCsv(FontInfo.listTables(font).csvStringArray(), fileName, i)); @@ -82,6 +81,8 @@ public class FontInfoMain { prependDataAndBuildCsv(FontInfo.listNameEntries(font).csvStringArray(), fileName, i)); System.out.println(); } else { + System.out.println(String.format("sfnt version: %s", FontInfo.sfntVersion(font))); + System.out.println(); System.out.println("Font Tables:"); FontInfo.listTables(font).prettyPrint(); System.out.println(); @@ -226,42 +227,6 @@ public class FontInfoMain { } } - /** - * Gets a Font object for a font file in the given path - * - * @param fontFile - * the path to the font file - * @return the Font object representing the font - * @throws IOException - * if font file does not exist or is invalid - */ - private static Font[] getFont(String fontFile) throws IOException { - return getFont(new FileInputStream(fontFile)); - } - - /** - * Gets a Font object for a font file in the InputStream - * - * @param is - * an InputStream containing the font file - * @return the Font object representing the font - * @throws IOException - * if font file or is invalid - */ - private static Font[] getFont(InputStream is) throws IOException { - FontFactory fontFactory = FontFactory.getInstance(); - fontFactory.fingerprintFont(true); - Font[] fonts = null; - - try { - fonts = fontFactory.loadFonts(is); - } finally { - is.close(); - } - - return fonts; - } - private static String prependDataAndBuildCsv(String[] arr, String fontName, int fontIndex) { StringBuilder output = new StringBuilder("Font,font index,").append(arr[0]).append('\n'); for (int i = 1; i < arr.length; i++) { diff --git a/java/src/com/google/typography/font/tools/fontinfo/FontSummary.java b/java/src/com/google/typography/font/tools/fontinfo/FontSummary.java deleted file mode 100644 index be4cc78..0000000 --- a/java/src/com/google/typography/font/tools/fontinfo/FontSummary.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright 2011 Google Inc. All Rights Reserved. - * - * 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 com.google.typography.font.tools.fontinfo; - -import com.google.typography.font.sfntly.Font; -import com.google.typography.font.sfntly.Font.PlatformId; -import com.google.typography.font.sfntly.Font.WindowsEncodingId; -import com.google.typography.font.sfntly.Tag; -import com.google.typography.font.sfntly.table.core.CMap; -import com.google.typography.font.sfntly.table.core.CMapTable; -import com.google.typography.font.sfntly.table.core.NameTable; -import com.google.typography.font.sfntly.table.core.NameTable.NameId; -import com.google.typography.font.sfntly.table.core.NameTable.WindowsLanguageId; -import com.google.typography.font.sfntly.table.truetype.Glyph; -import com.google.typography.font.sfntly.table.truetype.Glyph.GlyphType; -import com.google.typography.font.sfntly.table.truetype.GlyphTable; -import com.google.typography.font.sfntly.table.truetype.LocaTable; -import com.google.typography.font.sfntly.table.truetype.SimpleGlyph; - -import java.text.NumberFormat; - -/** - * Summarize a font's information - * @author Brian Stell - */ -public class FontSummary { - private final Font font; - private final long length; - - /** - * FontSummary constructor - * - * This constructor is needed since the font object does not know the file/bytearray size - * - * @param font - the font to summarize - * @param length - the length since the font object does not have that - */ - FontSummary(Font font, long length) { - this.font = font; - this.length = length; - } - - public String getCMapName() { - String cmapName = "unknown"; - - CMapTable cmapTable = font.getTable(Tag.cmap); - - if (cmapTable == null) { - throw new RuntimeException("Missing cmap table"); - } - CMap cmap = null; - // Try to get the UCS-4 cmap - cmap = cmapTable.cmap(Font.PlatformId.Windows.value(), - Font.WindowsEncodingId.UnicodeUCS4.value()); - if (cmap != null) { - cmapName = "USC-4"; - } else { - cmap = cmapTable.cmap(Font.PlatformId.Windows.value(), - Font.WindowsEncodingId.UnicodeUCS2.value()); - if (cmap != null) { - cmapName = "USC-2"; - } else { - throw new RuntimeException("Missing USC-4 and USC-2 cmap"); - } - } - - return cmapName; - } - - public String getFontFamilyName() { - return getNameTableEntry(NameId.FontFamilyName); - } - - public String getFontSubfamilyName() { - return getNameTableEntry(NameId.FontSubfamilyName); - } - - public long getGlyphsLength() { - LocaTable locaTable = font.getTable(Tag.loca); - int glyphsLength = 0; - - for (int glyphId = 0; glyphId < locaTable.numGlyphs(); glyphId++) { - if (glyphId != CMapTable.NOTDEF) { - // get the glyph length including any padding - glyphsLength += locaTable.glyphLength(glyphId); - } - } - return glyphsLength; - } - - public long getInstructionsLength() { - LocaTable locaTable = font.getTable(Tag.loca); - GlyphTable glyphTable = font.getTable(Tag.glyf); - int instructionsLength = 0; - - for (int glyphId = 0; glyphId < locaTable.numGlyphs(); glyphId++) { - if (glyphId != CMapTable.NOTDEF) { - int offset = locaTable.glyphOffset(glyphId); - int length = locaTable.glyphLength(glyphId); - if (length != 0) { // glyph objects only exist for non-zero length entries - Glyph glyph = glyphTable.glyph(offset, length); - if (glyph.glyphType() == GlyphType.Simple){ - int glyphLength = ((SimpleGlyph) glyph).dataLength(); - int instructionLength = ((SimpleGlyph) glyph).instructionSize(); - instructionsLength += instructionLength; - } - } - } - } - - return instructionsLength; - } - - public long getLength() { - return length; - } - - private String getNameTableEntry(NameId entryName) { - NameTable nameTable = font.getTable(Tag.name); - String value = nameTable.name(PlatformId.Windows.value(), - WindowsEncodingId.UnicodeUCS2.value(), WindowsLanguageId.English_UnitedStates.value(), - entryName.value()); - return value; - } - - public long getNumCodePoints() { - CMap cmap = null; - int maxCodePoint = 0xFFFF; - int numCodePoints = 0; - - CMapTable cmapTable = font.getTable(Tag.cmap); - if (cmapTable == null) { - throw new RuntimeException("Missing cmap table"); - } - - // Try to get the UCS-4 cmap - cmap = cmapTable.cmap(Font.PlatformId.Windows.value(), - Font.WindowsEncodingId.UnicodeUCS4.value()); - if (cmap != null) { - maxCodePoint = 0x10FFFF; - } else { - cmap = cmapTable.cmap(Font.PlatformId.Windows.value(), - Font.WindowsEncodingId.UnicodeUCS2.value()); - } - if (cmap != null) { - for (int charId = 0; charId < maxCodePoint; charId++) { - int glyphId = cmap.glyphId(charId); - if (glyphId != CMapTable.NOTDEF) { - numCodePoints += 1; - } - } - } else { - throw new RuntimeException("Missing USC-4 and USC-2 cmap"); - - } - - - return numCodePoints; - } - - public long getNumGlyphs() { - LocaTable locaTable = font.getTable(Tag.loca); - return locaTable.numGlyphs(); - } - - public String getVersion() { - double version = FontUtils.fixed1616ToDouble(font.sfntVersion()); - NumberFormat numberFormatter = NumberFormat.getInstance(); - numberFormatter.setMinimumFractionDigits(2); - numberFormatter.setGroupingUsed(false); - return numberFormatter.format(version); - } - - public String getVersionString() { - return getNameTableEntry(NameId.VersionString); - } -}
\ No newline at end of file diff --git a/java/src/com/google/typography/font/tools/fontinfo/FontUtils.java b/java/src/com/google/typography/font/tools/fontinfo/FontUtils.java index 06ca4e0..2bda290 100644 --- a/java/src/com/google/typography/font/tools/fontinfo/FontUtils.java +++ b/java/src/com/google/typography/font/tools/fontinfo/FontUtils.java @@ -16,13 +16,162 @@ package com.google.typography.font.tools.fontinfo; +import com.google.typography.font.sfntly.Font; +import com.google.typography.font.sfntly.FontFactory; +import com.google.typography.font.sfntly.Tag; +import com.google.typography.font.sfntly.table.Table; +import com.google.typography.font.sfntly.table.core.CMap; +import com.google.typography.font.sfntly.table.core.CMapTable; +import com.google.typography.font.sfntly.table.truetype.GlyphTable; +import com.google.typography.font.sfntly.table.truetype.LocaTable; + +import com.ibm.icu.lang.UCharacter; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + /** * Font Utility functions - * @author Brian Stell + * @author Brian Stell, Han-Wen Yeh */ public class FontUtils { - public static double fixed1616ToDouble(int val1616) { - return val1616/65536.0; // shift the decimal 16 bits + /** + * Gets a Font object for a font file in the given path + * + * @param fontFile + * the path to the font file + * @return the Font object representing the font + * @throws IOException + * if font file does not exist or is invalid + */ + public static Font[] getFonts(String fontFile) throws IOException { + return getFonts(new FileInputStream(fontFile)); + } + + /** + * Gets a Font object for a font file in the InputStream + * + * @param is + * an InputStream containing the font file + * @return the Font object representing the font + * @throws IOException + * if font file or is invalid + */ + public static Font[] getFonts(InputStream is) throws IOException { + FontFactory fontFactory = FontFactory.getInstance(); + fontFactory.fingerprintFont(true); + Font[] fonts = null; + + try { + fonts = fontFactory.loadFonts(is); + } finally { + is.close(); + } + + return fonts; + } + + /** + * Gets the table with the specified tag for the given font + * + * @param font + * the source font + * @param tag + * the tag for the table to return + * @return the specified table for the given font + * @throws UnsupportedOperationException + * if the font does not contain the table with the specified tag + * @see Tag + */ + public static Table getTable(Font font, int tag) { + Table table = font.getTable(tag); + if (table == null) { + throw new RuntimeException("Font has no " + Tag.stringValue(tag) + " table"); + } + return table; + } + + /** + * Gets the cmap table for the given font + * + * @param font + * the source font + * @return the cmap table for the given font + * @throws UnsupportedOperationException + * if the font does not contain a valid cmap table + */ + public static CMapTable getCMapTable(Font font) { + return (CMapTable) getTable(font, Tag.cmap); + } + + /** + * Gets either a UCS4 or UCS2 cmap, if available + * + * @param font + * the source font + * @return the UCS4 or UCS2 cmap + * @throws UnsupportedOperationException + * if font does not contain a UCS-4 or UCS-2 cmap + */ + public static CMap getUCSCMap(Font font) { + CMapTable cmapTable = getCMapTable(font); + + // Obtain the UCS-4 cmap. If it doesn't exist, then obtain the UCS-2 cmap + CMap cmap = null; + cmap = cmapTable.cmap( + Font.PlatformId.Windows.value(), Font.WindowsEncodingId.UnicodeUCS4.value()); + if (cmap == null) { + cmap = cmapTable.cmap( + Font.PlatformId.Windows.value(), Font.WindowsEncodingId.UnicodeUCS2.value()); + } + if (cmap == null) { + throw new UnsupportedOperationException("Font has no UCS-4 or UCS-2 cmap"); + } + + return cmap; + } + + /** + * Gets the loca table for the given font + * + * @param font + * the source font + * @return the loca table for the given font + * @throws UnsupportedOperationException + * if the font does not contain a valid loca table + */ + public static LocaTable getLocaTable(Font font) { + return (LocaTable) getTable(font, Tag.loca); + } + + /** + * Gets the glyph table for the given font + * + * @param font + * the source font + * @return the glyph table for the given font + * @throws UnsupportedOperationException + * if the font does not contain a valid glyph table + */ + public static GlyphTable getGlyphTable(Font font) { + return (GlyphTable) getTable(font, Tag.glyf); } + /** + * Gets a string version of the code point formatted as "U+hhhh" or "U+hhhhhh" + * + * @param codePoint + * the code point to format + * @return a formatted version of the code point as a string + */ + public static String getFormattedCodePointString(int codePoint) { + if (UCharacter.isValidCodePoint(codePoint)) { + if (UCharacter.isBMP(codePoint)) { + return String.format("U+%04X", codePoint); + } + return String.format("U+%06X", codePoint); + } + throw new IllegalArgumentException("Invalid code point " + codePoint); + } }
\ No newline at end of file diff --git a/java/src/com/google/typography/font/tools/fontinfo/ReportFontSummary.java b/java/src/com/google/typography/font/tools/fontinfo/ReportFontSummary.java deleted file mode 100644 index 141f054..0000000 --- a/java/src/com/google/typography/font/tools/fontinfo/ReportFontSummary.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2011 Google Inc. All Rights Reserved. - * - * 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 com.google.typography.font.tools.fontinfo; - -import com.google.typography.font.sfntly.Font; -import com.google.typography.font.sfntly.FontFactory; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.text.DecimalFormat; -import java.util.logging.Logger; - -/** - * A tool to report a summary of a font's information. - * @author Brian Stell - */ -public class ReportFontSummary { - private static final Logger logger = - Logger.getLogger(Font.class.getCanonicalName()); - - /** - * Main function: read input args, create and report the font summary. - * - * @param args - command line arguments - */ - public static void main(String[] args) { - - boolean reportCsv = false; - - int argPos = 0; - for (; argPos < args.length; argPos++) { - String option = null; - if (args[argPos].charAt(0) != '-') { - break; - } - option = args[argPos].substring(1); - - if (option == null) { - printUsage(); - System.exit(0); - } - if (option.equals("csv")) { - reportCsv = true; - } else { - printUsage(); - System.exit(0); - } - } - - boolean reportedCsvHeader = false; - FontFactory fontFactory = FontFactory.getInstance(); - - for (; argPos < args.length; argPos++) { - ReportFontSummary fontinfo = new ReportFontSummary(); - File fontFile = null; - - try { - fontFile = new File(args[argPos]); - FileInputStream fis = new FileInputStream(fontFile); - long length = fontFile.length(); - Font[] fontArray = fontFactory.loadFonts(fis); - for (Font font : fontArray) { - FontSummary fontSummary = new FontSummary(font, length); - if (reportCsv) { - if (!reportedCsvHeader) { - reportedCsvHeader = true; - System.out.println("Family Name,Style,Version,File Size,Cmap,# CodePoints," - + "# Glyphs,#Glyph Bytes,# Instruction Bytes"); - } - fontinfo.reportSummaryCsv(fontSummary); - } else { - fontinfo.reportSummary(fontSummary); - } - } - } catch (IOException e) { - logger.severe(e.getLocalizedMessage()); - System.exit(0); - } - } - } - - /** - * Help message that describes usage and input parameters - */ - private static final void printUsage() { - System.err.println("FontInfo [options] fontfile [...]"); - System.err.println("\t-csv\tprint results as csv"); - System.err.println("\t-h,--help\tprint this help information"); - } - - /** - * Report the summary in a CSV format - * - * @param fontSummary the object that summarizes font values - */ - public void reportSummary(FontSummary fontSummary) { - DecimalFormat formatter = new DecimalFormat("#,###,###"); - System.out.println(" Family: " + fontSummary.getFontFamilyName()); - System.out.println(" Subfamily: " + fontSummary.getFontSubfamilyName()); - System.out.println(" Version: " + fontSummary.getVersion()); - System.out.println(" Length: " + formatter.format(fontSummary.getLength())); - System.out.println(" CMap: " + fontSummary.getCMapName()); - System.out.println("Code Points: " + formatter.format(fontSummary.getNumCodePoints())); - System.out.println(" Glyphs: " + formatter.format(fontSummary.getNumGlyphs())); - System.out.println("Glyph Bytes: " + formatter.format(fontSummary.getGlyphsLength())); - System.out.println(" BCI Bytes: " + formatter.format(fontSummary.getInstructionsLength())); - System.out.println(); - } - - /** - * Report the summary in a CSV format - * - * @param fontSummary the object that summarizes font values - */ - public void reportSummaryCsv(FontSummary fontSummary) { - System.out.print(fontSummary.getFontFamilyName()); - System.out.print(","); - System.out.print(fontSummary.getFontSubfamilyName()); - System.out.print(","); - System.out.print(fontSummary.getVersion()); - System.out.print(","); - System.out.print(fontSummary.getLength()); - System.out.print(","); - System.out.print(fontSummary.getCMapName()); - System.out.print(","); - System.out.print(fontSummary.getNumCodePoints()); - System.out.print(","); - System.out.print(fontSummary.getNumGlyphs()); - System.out.print(","); - System.out.print(fontSummary.getGlyphsLength()); - System.out.print(","); - System.out.print(fontSummary.getInstructionsLength()); - System.out.println(); - } -} |