aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryehh <yehh@google.com>2012-08-15 21:58:18 +0000
committeryehh <yehh@google.com>2012-08-15 21:58:18 +0000
commitfe684ca7642f00019417272f69b6898d255272f4 (patch)
tree0a303fe3de025a93234ed2a5f5d2629ab160b170
parent4a07f45e822ecf6f7a05eee07a6617e80ca280b2 (diff)
downloadsfntly-fe684ca7642f00019417272f69b6898d255272f4.tar.gz
Merging Brian's font tool into Han-Wen's
CL @ http://codereview.appspot.com/6462061/
-rw-r--r--java/src/com/google/typography/font/sfntly/math/Fixed1616.java8
-rw-r--r--java/src/com/google/typography/font/tools/fontinfo/FontInfo.java168
-rw-r--r--java/src/com/google/typography/font/tools/fontinfo/FontInfoMain.java47
-rw-r--r--java/src/com/google/typography/font/tools/fontinfo/FontSummary.java190
-rw-r--r--java/src/com/google/typography/font/tools/fontinfo/FontUtils.java155
-rw-r--r--java/src/com/google/typography/font/tools/fontinfo/ReportFontSummary.java150
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();
- }
-}