Java Source Code : 康煕部首文字を含むフォント一覧
Java Source Code : 康煕部首文字を含むフォント一覧
「康煕部首文字を含んでいるフォント」のフォントファイルを全て抽出し、一覧にするJavaプログラムを作ったので公開します。
実行結果は、康煕部首文字を含むフォント一覧のとおりです。
フォントファイルの内部構造(仕様)は、The OpenType Font Fileに書かれています。
この仕様を読んだだけだと、イメージがわきにくいので、本sorce codeを併せて読めば、理解し易くなると思われます。
実行する前の準備(環境はWindows10)
1.C://Users/Public/Documents/myFontsフォルダーを作成する。
2.C:\Windows\Fontsにあるフォントを全て、上記1で作成したフォルダーにコピーする。
3.本プログラムを実行させる。(実行のさせ方は、各自で調べてください)
4.上記1のフォルダーに000勇者ああああ.txtファイルが上書き作成され、そこにフォント一覧が記載されている。
実行結果は、康煕部首文字を含むフォント一覧のとおりです。
フォントファイルの内部構造(仕様)は、The OpenType Font Fileに書かれています。
この仕様を読んだだけだと、イメージがわきにくいので、本sorce codeを併せて読めば、理解し易くなると思われます。
実行する前の準備(環境はWindows10)
1.C://Users/Public/Documents/myFontsフォルダーを作成する。
2.C:\Windows\Fontsにあるフォントを全て、上記1で作成したフォルダーにコピーする。
3.本プログラムを実行させる。(実行のさせ方は、各自で調べてください)
4.上記1のフォルダーに000勇者ああああ.txtファイルが上書き作成され、そこにフォント一覧が記載されている。
//以下、Java source code
package module;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
//https://docs.microsoft.com/ja-jp/typography/opentype/spec/otff
public class mainProgram {
static private String sDir = new String("C://Users/Public/Documents/myFonts");
public static class classTags {
public int iThisRecordID;
public int iTagID;
public String sTagName;
public String sDiscription;
public long lgLength;
public long lgOffset;
public long lgCheckSum;
public classTags(){
iThisRecordID = 0;
iTagID = 0;
sTagName = null;
sDiscription = null;
lgLength = 0;
lgOffset = 0;
lgCheckSum = 0;
}
public int getIDTag() {
return iTagID;
}
public String getTagName() {
return sTagName;
}
}
public static ArrayList<classTags> cTs = null;
private static PrintWriter fw;
private static int hasKangxiRadicals;
private static String sNameOfFont = "";
private static class classTagsCompare implements Comparator<classTags> {
public int compare(classTags c1, classTags c2) {
if(c1.getIDTag() < c2.getIDTag()) {
return -1;
}
else {
if(c1.getIDTag() > c2.getIDTag()) return 1;
else return c1.getTagName().compareTo(c2.getTagName());
}
}
}
public static void main(String[] args) {
System.out.println("start of program");
RandomAccessFile f;
int iCounter, iTTFiles;
try {
fw = new PrintWriter(sDir + "/000勇者ああああ.txt");
fw.println("analyze font files");
}
catch (IOException ex) {
ex.printStackTrace();
System.exit(0);
}
File dir = new File(sDir);
File[] list = dir.listFiles();
iTTFiles = 0;
for(iCounter = 0; iCounter<list.length; iCounter++) {
String s;
s = list[iCounter].getName();
s.toLowerCase();
if(s.endsWith(".ttc")) {
boolean bRet = true;
iTTFiles++;
s = list[iCounter].getAbsolutePath();
System.out.println(s);
try {
f = new RandomAccessFile(s, "r");
fw.print(String.valueOf(iTTFiles) + " " + s);
bRet = proceed_ttc(f);
f.close();
}
catch(FileNotFoundException e) {
System.out.println(e);
System.exit(0);
}
catch(IOException e) {
System.out.println(e);
System.exit(0);
}
if(bRet==false) break;
}
else {
if(s.endsWith(".ttf")) {
boolean bRet = true;
iTTFiles++;
s = list[iCounter].getAbsolutePath();
System.out.println(s);
try {
f = new RandomAccessFile(s, "r");
fw.print(String.valueOf(iTTFiles) + " " + s);
bRet = proceedFontTable_ttf(f);
f.close();
}
catch(FileNotFoundException e) {
System.out.println(e);
System.exit(0);
}
catch(IOException e) {
System.out.println(e);
System.exit(0);
}
if(bRet==false) break;
}
}
}
fw.close();
System.out.println("Number of all font files : " + String.valueOf(iTTFiles));
System.out.println("end of program");
}
static private boolean proceed_ttc(RandomAccessFile f) {
long lgOffsetFonts[];
lgOffsetFonts = proceedHeader(f);
if(lgOffsetFonts==null) return false;
else return proceedFontTable(f, lgOffsetFonts);
}
static private long[] proceedHeader(RandomAccessFile f) {
int iMajorV,iValue;
byte b4[] = new byte[4];
try {
f.read(b4);
}
catch(IOException e) {
System.out.println(e);
return null;
}
String s4 = new String(b4);
if(s4.toString().equals("ttcf")) System.out.println("This is " + s4);
else {
System.out.println("error : " + s4 + " is not ttcf");
return null;
}
iMajorV = get16(f, 0);
if(iMajorV == -1) return null;
System.out.println("major version : " + String.valueOf(iMajorV));
iValue = get16(f, 0);
if(iValue == -1) return null;
System.out.println("minor version : " + String.valueOf(iValue));
long lgMax;
lgMax = get32(f, 0);
if(lgMax == -1) return null;
System.out.println("number of fonts : " + String.valueOf(lgMax));
long lgOffsetFonts[] = new long[(int) lgMax];
for(long lg=0; lg<lgMax ; lg++) {
long lgValue;
lgValue = get32(f, 0);
lgOffsetFonts[(int)lg] = lgValue;
System.out.println(" offset : 0x" + Long.toHexString(lgValue));
}
if(iMajorV==2) {
try {
f.read(b4);
}
catch(IOException e) {
System.out.println(e);
return null;
}
s4 = new String(b4);
if(s4.toString().equals("DSIG")) {
System.out.println("DSIG - Digital Signature - Other OpenType Tables");
long lg;
lg = get32(f, 0);
if(lg == -1) return null;
System.out.println(" length : " + String.valueOf(lg));
lg = get32(f, 0);
if(lg == -1) return null;
System.out.println(" offset : 0x" + Long.toHexString(lg));
}
else {
if(b4[0]==0) {
System.out.println("This font has no DSIG, although major version is 2.");
get32(f, 0);
get32(f, 0);
}
else {
System.out.println("*** error : proceedHeader() " + s4 + " is not DSIG");
return null;
}
}
}
return lgOffsetFonts;
}
static private boolean proceedFontTable_ttf (RandomAccessFile f) {
hasKangxiRadicals = 0;
long lgValue;
lgValue = get32(f, 0);
if(lgValue == -1) return false;
if(lgValue==0x10000) {
System.out.println("This font has TrueType outlines");
}
else {
if(lgValue==0x4F54544F) {
System.out.println("This font has CFF data");
}
else {
System.out.println("error : proceedFontTable_ttf() at sfntVersion");
return false;
}
}
boolean bRet;
bRet = getFontTable(f);
if(bRet==false) {
return false;
}
if(hasKangxiRadicals==0) {
fw.println(" has no Kangxi Radical");
}
return true;
}
static private boolean proceedFontTable(RandomAccessFile f, long lgOffsetFonts[]) {
int i, iSize = lgOffsetFonts.length;
hasKangxiRadicals = 0;
for(i=0; i<iSize; i++) {
long lgOffset = lgOffsetFonts[i], lgValue;
try {
f.seek(lgOffset);
}
catch (IOException e) {
e.printStackTrace();
return false;
}
lgValue = get32(f, 0);
if(lgValue == -1) return false;
if(lgValue==0x10000) {
System.out.println("font[" + String.valueOf(i) + "] : has TrueType outlines");
}
else {
if(lgValue==0x4F54544F) {
System.out.println("*** font[" + String.valueOf(i) + "] : has CFF data");
}
else {
System.out.println("error : font[" + String.valueOf(i) + "] : at sfntVersion");
return false;
}
}
boolean bRet;
bRet = getFontTable(f);
if(bRet==false) {
return false;
}
}
if(hasKangxiRadicals==0) {
fw.println(" has no Kangxi Radical");
}
return true;
}
static private boolean getFontTable(RandomAccessFile f) {
int i, iTables;
iTables = get16(f, 0);
if(iTables == -1) return false;
System.out.println(" number of Tables : " + String.valueOf(iTables));
i = get16(f, 0);
if(i == -1) return false;
System.out.println(" searchRange : " + String.valueOf(i));
i = get16(f, 0);
if(i == -1) return false;
System.out.println(" entrySelector : " + String.valueOf(i));
i = get16(f, 0);
if(i == -1) return false;
System.out.println(" rangeShift : " + String.valueOf(i));
ArrayList<classTags> cTs = new ArrayList<>();
for(i=0; i<iTables; i++) {
classTags ct = new classTags();
ct.iThisRecordID= i;
byte b4[] = new byte[4];
try {
f.read(b4);
}
catch(IOException e) {
System.out.println(e);
return false;
}
ct.sTagName = new String(b4);
if(getTableTag(ct)==false) return false;
long lgValue = get32(f, 0);
if(lgValue == -1) return false;
ct.lgCheckSum = lgValue;
lgValue = get32(f, 0);
if(lgValue == -1) return false;
ct.lgOffset = lgValue;
lgValue = get32(f, 0);
if(lgValue == -1) return false;
ct.lgLength = lgValue;
cTs.add(ct);
}
Collections.sort(cTs, new classTagsCompare());
int iTag = cTs.get(0).iTagID;
printTagGroupName(iTag);
for(i=0; i<iTables; i++) {
boolean bRet;
if(iTag!=cTs.get(i).iTagID) {
iTag = cTs.get(i).iTagID;
printTagGroupName(iTag);
}
System.out.println(" " + cTs.get(i).sTagName + " - " + cTs.get(i).sDiscription);
switch(cTs.get(i).sTagName) {
case "cmap":
bRet = cmap(f, cTs.get(i).lgOffset);
if(bRet==false) return false;
break;
case "name":
bRet = name(f, cTs.get(i).lgOffset);
if(bRet==false) return false;
break;
}
}
if(hasKangxiRadicals>=1) {
if(hasKangxiRadicals==1) {
fw.println(" has Kangxi Radical");
}
fw.println(sNameOfFont);
sNameOfFont = "";
}
return true;
}
static private boolean name(RandomAccessFile f, long lgOffset) {
long lgOffsetStorage = lgOffset, lgOffsetNameRecode = lgOffset;
int i, iCounter, j, iNames;
String s;
i = get16(f, lgOffset);
lgOffsetNameRecode += 2;
System.out.println(" format : " + String.valueOf(i));
iNames = get16(f, 0);
lgOffsetNameRecode += 2;
System.out.println(" number of name records : " + String.valueOf(iNames));
i = get16(f, 0);
lgOffsetNameRecode += 2;
lgOffsetStorage += i;
System.out.println(" stringOffset : 0x" + Long.toHexString(i));
String s1J="", s1nJ="", s2J="", s2nJ="";
//Name Records
for(iCounter=0; iCounter<iNames; iCounter++) {
int iPlatformID, iEncordingID, iLanguage, iNameID, iLength, iLength2;
long lgOffsetString;
lgOffsetString = lgOffsetStorage;
iPlatformID = get16(f, lgOffsetNameRecode);
lgOffsetNameRecode += 2;
s = " - platform ID : " + String.valueOf(iPlatformID);
switch(iPlatformID) {
case 0: s += " for Unicode"; break;
case 1: s += " for Macintosh"; break;
case 2: s += " for ISO [deprecated]"; break;
case 3: s += " for Windows"; break;
case 4: s += " for Custom"; break;
default:
System.out.println("error : name() " + s);
return false;
}
System.out.println(s);
iEncordingID = get16(f, 0);
lgOffsetNameRecode += 2;
s = " encording ID : " + String.valueOf(iEncordingID);
switch(iPlatformID) {
case 0:
switch(iEncordingID) {
case 0: s += " 1.0 semantics"; break;
case 1: s += " 1.1 semantics"; break;
case 2: s += " ISO/IEC 10646 semantics"; break;
case 3: s += " BMP only"; break;
case 4: s += " full repertoire"; break;
case 5: s += " Variation Sequences"; break;
case 6: s += " full repertoire"; break;
default:
System.out.println("* error : name() " + s);
return false;
}
break;
case 1:
break;
case 3:
switch(iEncordingID) {
case 0: s += " for Symbol"; break;
case 1: s += " for Unicode BMP"; break;
case 2: s += " for ShiftJIS"; break;
case 3: s += " for PRC"; break;
case 4: s += " for Big5"; break;
case 5: s += " for Wansung"; break;
case 6: s += " for Johab"; break;
case 7: s += " Reserved"; break;
case 8: s += " Reserved"; break;
case 9: s += " Reserved"; break;
case 10: s += " for Unicode full repertoire"; break;
default:
System.out.println("error : name() " + s);
return false;
}
break;
default:
System.out.println("* error : not programed. name() " + s);
return false;
}
System.out.println(s);
String sEncording = "UTF-16";
iLanguage= get16(f, 0);
lgOffsetNameRecode += 2;
s = " language ID : 0x" + Long.toHexString(iLanguage);
switch(iLanguage) {
case 0x0000:
if(iPlatformID==1 || iPlatformID==3) sEncording = "UTF-8";
break;
case 0x0403: s += " Catalan Catalan"; break;
case 0x0405: s += " Czech Czech Republic"; break;
case 0x0406: s += " Danish Denmark"; break;
case 0x0407: s += " German Germany"; break;
case 0x0408: s += " Greek Greece"; break;
case 0x0409: s += " English United States"; break;
case 0x040a: s += " Spanish (Traditional Sort) Spain"; break;
case 0x040b: s += " Finnish Finland"; break;
case 0x040c: s += " French France"; break;
case 0x040e: s += " Hungarian Hungary"; break;
case 0x0410: s += " Italian Italy"; break;
case 0x0411: s += " Japanese Japan"; break;
case 0x0413: s += " Dutch Netherlands"; break;
case 0x0414: s += " Norwegian (Bokmal) Norway"; break;
case 0x0415: s += " Polish Poland"; break;
case 0x0416: s += " Portuguese Brazil"; break;
case 0x0419: s += " Russian Russia"; break;
case 0x041b: s += " Slovak Slovakia"; break;
case 0x041d: s += " Swedish Sweden"; break;
case 0x041f: s += " Turkish Turkey"; break;
case 0x0424: s += " Slovenian Slovenia"; break;
case 0x042d: s += " Basque Basque"; break;
case 0x080a: s += " Spanish Mexico"; break;
case 0x0816: s += " Portuguese Portugal"; break;
case 0x0c0a: s += " Spanish (Modern Sort) Spain"; break;
case 0x0c0c: s += " French Canada"; break;
default: s += " *** not programed ***"; break;
}
System.out.println(s);
iNameID = get16(f, 0);
lgOffsetNameRecode += 2;
s = " name ID : " + String.valueOf(iNameID);
switch(iNameID) {
case 0: s += " Copyright notice"; break;
case 1: s += " Font Family name"; break;
case 2: s += " Font Subfamily name"; break;
case 3: s += " Unique font identifier"; break;
case 4: s += " Full font name"; break;
case 5: s += " Version string"; break;
case 6: s += " PostScript name"; break;
case 7: s += " Trademark"; break;
case 8: s += " Manufacturer Name"; break;
case 9: s += " Designer"; break;
case 10: s += " description of the typeface"; break;
case 11: s += " URL of font vendor"; break;
case 12: s += " URL of typeface designer"; break;
case 13: s += " License Description"; break;
case 14: s += " License Info URL"; break;
case 15: s += " Reserved"; break;
case 16: s += " Typographic Family name"; break;
case 17: s += " Typographic Subfamily name"; break;
case 18: s += " Compatible Full (Macintosh only)"; break;
case 19: s += " Sample text"; break;
default: s += " *** not programed"; break;
}
System.out.println(s);
iLength= get16(f, 0);
lgOffsetNameRecode += 2;
System.out.println(" length : " + String.valueOf(iLength) + " bytes");
j= get16(f, 0);
lgOffsetNameRecode += 2;
lgOffsetString = lgOffsetStorage + j;
System.out.println(" offset : 0x" + Long.toHexString(j));
if(iLength>200) iLength2 = 200;
else iLength2 = iLength;
byte b[] = new byte[iLength2];
try {
f.seek(lgOffsetString);
f.read(b);
}
catch(IOException e) {
System.out.println(e);
return false;
}
try {
s = new String(b, sEncording);
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
if(iLength>200) s += "...";
System.out.println(" " + s);
if(iLanguage==0x0411) {
if(iNameID==1) s1J = s;
else if(iNameID==5) s2J = s;
}
else {
if(iNameID==1) s1nJ = s;
else if(iNameID==5) s2nJ = s;
}
}
if(s1J.equals("")) {
sNameOfFont = s1nJ + " " + s2nJ;
}
else {
sNameOfFont = s1J + " " + s2J;
}
return true;
}
static private boolean cmap(RandomAccessFile f, long lgOffset) {
long lgAdressStart = lgOffset, lgProgress, lg;
int i, j, iNumTables, iCounter;
boolean bHasKangxiRadicals = false;
//cmap Header
i = get16(f, lgOffset);
lgAdressStart += 2;
System.out.println(" version : " + String.valueOf(i));
iNumTables = get16(f, 0);
lgAdressStart += 2;
System.out.println(" number of tables : " + String.valueOf(iNumTables));
lgProgress = 0;
for(iCounter = 0; iCounter<iNumTables; iCounter++) {
//ncoding records and encodings
int iK, iPlatformID, iEncordingID, iFormat, iValue;
long lgGroupings, lgValue;
iPlatformID = get16(f, lgAdressStart + lgProgress);
lgProgress += 2;
iEncordingID = get16(f, 0);
lgProgress += 2;
String s = " - platform ID : ";
switch(iPlatformID) {
case 0: s += " " + String.valueOf(iPlatformID) + ". for Unicode"; break;
case 1: s += " " + String.valueOf(iPlatformID) + ". for Macintosh"; break;
case 3:
s += " " + String.valueOf(iPlatformID) + ". for Windows";
System.out.println(s);
switch(iEncordingID) {
case 0: s = " Symbol"; break;
case 1: s = " Unicode BMP"; break;
case 10: s = " Unicode full repertoire"; break;
default: s = "*** cmap() not programed at EncordingID"; break;
}
break;
default: s += " " + String.valueOf(iPlatformID) + ". error"; break;
}
System.out.println(s);
System.out.println(" encording ID : " + String.valueOf(iEncordingID));
lg = get32(f, 0);//Byte offset from beginning of table to the subtable for this encoding
lgProgress += 4;
System.out.println(" offset : 0x" + String.valueOf(lg));
lg += lgOffset;
switch(iPlatformID) {
case 0://for Unicode. Format 14: Unicode Variation Sequences
i = get16(f, lg);
if(i==14) {
System.out.println(" format : 14 Unicode Variation Sequences");
lg = get32(f, 0);
System.out.println(" length : 0x" + Long.toHexString(lg));
lg = get32(f, 0);
System.out.println(" numVarSelectorRecords : 0x" + Long.toHexString(lg));
}
else {
System.out.println(" format : " + String.valueOf(i));
System.out.println(" *** error format is NOT 14 Unicode Variation Sequences");
}
break;
case 1: //Macintosh platform
System.out.println(" format : 1 Macintosh platform");
break;
case 3: //for Windows
iFormat = get16(f, lg);
switch(iEncordingID) {
case 0:
case 1://format: 4 Segment mapping to delta values
if(iFormat==4) System.out.println(" format: 4 Segment mapping to delta values");
else {
System.out.println("*** error cmap() format : " + String.valueOf(iFormat));
return false;
}
i = get16(f, 0);
System.out.println(" length : " + String.valueOf(i));
i = get16(f, 0);
System.out.println(" language : " + String.valueOf(i));
j = get16(f, 0);
System.out.println(" segCountX2 : " + String.valueOf(j));
i = get16(f, 0);
System.out.println(" searchRange : " + String.valueOf(i));
i = get16(f, 0);
System.out.println(" entrySelector : " + String.valueOf(i));
i = get16(f, 0);
System.out.println(" rangeShift : " + String.valueOf(i));
i = get16(f, 0);
System.out.println(" endCode[0] : 0x" + Long.toHexString(i));
iValue = 0;
j /= 2;
j--;
for(i=0; i<j; i++) {
iValue = get16(f, 0);
}
System.out.println(" endCode[last] : 0x" + Long.toHexString(iValue));
i = get16(f, 0);
System.out.println(" reservedPad : " + String.valueOf(i));//Set to 0.
i = get16(f, 0);
System.out.println(" startCode[0] : 0x" + Long.toHexString(i));
iK = 0;
iValue = 0;
for(i=0; i<j; i++) {
iValue = get16(f, 0);
if(
iValue>=0x2f00 && iValue<=0x2fdf
|| iValue>=0x2e80 && iValue<=0x2eff
) {
bHasKangxiRadicals = true;
//Kangxi Radicals Range: 2F00–2FDF
//CJK Radicals Supplement Range: 2E80–2EFF
iK++;
System.out.println(" * Kangxi Radicals start Unicode 0x" + Long.toHexString(iValue));
}
}
if(iK==0) {
System.out.println(" endCode[last] : 0x" + Long.toHexString(iValue));
System.out.println(" This font has no Kangxi Radicals");
}
else {
System.out.println(" *** found Kangxi Radicals");
}
break;
case 10://format:12 Segmented coverage
if(iFormat!=12) {
System.out.println("*** error cmap() format not 12");
return false;
}
System.out.println(" format:12 Segmented coverage");
i = get16(f, 0);
if(i==0) System.out.println(" Reserved; set to 0");
else {
System.out.println("*** error cmap() Reserved; set to 0");
return false;
}
lg = get32(f, 0);//Byte length of this subtable (including the header)
System.out.println(" length : 0x" + Long.toHexString(lg));
lg = get32(f, 0);//For requirements on use of the language field
//The language field must be set to zero
System.out.println(" Language : " + String.valueOf(lg));
lgGroupings = get32(f, 0);//Number of groupings which follow
System.out.println(" number of groupings : " + String.valueOf(lgGroupings));
iK = 0;
for(lg=0; lg<lgGroupings; lg++) {
lgValue = get32(f, 0);
get32(f, 0);
get32(f, 0);
if(
lgValue>=0x2f00 && lgValue<=0x2fdf
|| lgValue>=0x2e80 && lgValue<=0x2eff
) {
//Kangxi Radicals Range: 2F00–2FDF
bHasKangxiRadicals = true;
iK++;
}
}
if(iK==0) {
System.out.println(" This font has no Kangxi Radicals");
}
else{
System.out.println(" *** found Kangxi Radicals. number is " + String.valueOf(iK));
}
break;
default:
System.out.println("*** error cmap() not programed format : "+ String.valueOf(iFormat));
return false;
}
break;
default:
System.out.println("*** error cmap() iPlatformID");
return false;
}
}
if(bHasKangxiRadicals) {
hasKangxiRadicals++;
}
return true;
}
static private boolean printTagGroupName(int iTagID) {
boolean bRet = true;
switch(iTagID) {
case 0:
System.out.println("- Required Tables");
break;
case 1:
System.out.println("- Tables Related to TrueType Outlines");
break;
case 2:
System.out.println("- Tables Related to Bitmap Glyphs");
break;
case 3:
System.out.println("- Advanced Typographic Tables");
break;
case 4:
System.out.println("- Tables used for OpenType Font Variations");
break;
case 5:
System.out.println("- Tables Related to Color Fonts");
break;
case 6:
System.out.println("- Other OpenType Tables");
break;
default:
System.out.println("not programed at printTagGroupName()");
bRet = false;
break;
}
return bRet;
}
static private boolean getTableTag(classTags cT) {
boolean bRet = true;
switch(cT.sTagName) {
//Required Tables
case "cmap":
cT.sDiscription = "Character to Glyph Index Mapping";
cT.iTagID = 0;
break;
case "OS/2":
cT.sDiscription = "OS/2 and Windows Metrics";
cT.iTagID = 0;
break;
case "head":
cT.sDiscription = "Font Header";
cT.iTagID = 0;
break;
case "hhea":
cT.sDiscription = "Horizontal Header";
cT.iTagID = 0;
break;
case "hmtx":
cT.sDiscription = "Horizontal Metrics";
cT.iTagID = 0;
break;
case "maxp":
cT.sDiscription = "Maximum Profile";
cT.iTagID = 0;
break;
case "name":
cT.sDiscription = "Naming";
cT.iTagID = 0;
break;
case "post":
cT.sDiscription = "PostScript";
cT.iTagID = 0;
break;
//Tables Related to TrueType Outlines
case "cvt ":
cT.sDiscription = "Control Value";
cT.iTagID = 1;
break;
case "fpgm":
cT.sDiscription = "Font Program";
cT.iTagID = 1;
break;
case "gasp":
cT.sDiscription = "Grid-fitting and Scan-conversion Procedure";
cT.iTagID = 1;
break;
case "glyf":
cT.sDiscription = "Glyph Data";
cT.iTagID = 1;
break;
case "loca":
cT.sDiscription = "Index to Location";
cT.iTagID = 1;
break;
case "prep":
cT.sDiscription = "Control Value Program";
cT.iTagID = 1;
break;
//Tables Related to Bitmap Glyphs
case "EBDT":
cT.sDiscription = "Embedded Bitmap Data";
cT.iTagID = 2;
break;
case "EBLC":
cT.sDiscription = "Embedded Bitmap Location";
cT.iTagID = 2;
break;
//Advanced Typographic Tables
case "BASE":
cT.sDiscription = "Baseline";
cT.iTagID = 3;
break;
case "GDEF":
cT.sDiscription = "Glyph Definition";
cT.iTagID = 3;
break;
case "GPOS":
cT.sDiscription = "Glyph Positioning";
cT.iTagID = 3;
break;
case "GSUB":
cT.sDiscription = "Glyph Substitution";
cT.iTagID = 3;
break;
case "MATH":
cT.sDiscription = "mathematical typesetting table";
cT.iTagID = 3;
break;
case "JSTF":
cT.sDiscription = "Justification Table";
cT.iTagID = 3;
break;
//Tables used for OpenType Font Variations
case "avar":
cT.sDiscription = "Axis Variations Table";
cT.iTagID = 4;
break;
case "fvar":
cT.sDiscription = "Font Variations Table";
cT.iTagID = 4;
break;
case "gvar":
cT.sDiscription = "Glyph Variations Table";
cT.iTagID = 4;
break;
case "STAT":
cT.sDiscription = "Style Attributes Table";
cT.iTagID = 4;
break;
case "HVAR":
cT.sDiscription = "Horizontal Metrics Variations Table";
cT.iTagID = 4;
break;
case "MVAR":
cT.sDiscription = "Metrics Variations Table";
cT.iTagID = 4;
break;
//Tables Related to Color Fonts
case "COLR":
cT.sDiscription = "Color Table";
cT.iTagID = 5;
break;
case "CPAL":
cT.sDiscription = "Color Palette Table";
cT.iTagID = 5;
break;
//Other OpenType Tables
case "meta":
cT.sDiscription = "Metadata";
cT.iTagID = 6;
break;
case "vhea":
cT.sDiscription = "Vertical Header";
cT.iTagID = 6;
break;
case "vmtx":
cT.sDiscription = "Vertical Metrics";
cT.iTagID = 6;
break;
case "LTSH":
cT.sDiscription = "Linear Threshold";
cT.iTagID = 6;
break;
case "MERG":
cT.sDiscription = "Merge";
cT.iTagID = 6;
break;
case "kern":
cT.sDiscription = "Kerning";
cT.iTagID = 6;
break;
case "VDMX":
cT.sDiscription = "Vertical Device Metrics";
cT.iTagID = 6;
break;
case "hdmx":
cT.sDiscription = "Horizontal Device Metrics";
cT.iTagID = 6;
break;
case "DSIG":
cT.sDiscription = "Digital Signature Table";
cT.iTagID = 6;
break;
case "PCLT":
cT.sDiscription = "PCL 5 Table";
cT.iTagID = 6;
break;
case "ASCP":
case "bdat":
case "bloc":
cT.sDiscription = "*** I dont know such a thing!!!";
cT.iTagID = 6;
break;
//error
default:
cT.sDiscription = "not programed !";
cT.iTagID = -1;
bRet = false;
System.out.println("*** getTableTag() not programed : " + cT.sTagName);
break;
}
return bRet;
}
static private int get16(RandomAccessFile f, long lgOffset) {
int retInt;
byte b2[] = new byte[2];
try {
if(lgOffset>0) {
f.seek(lgOffset);
}
f.read(b2);
}
catch(IOException e) {
System.out.println(e);
return(-1);
}
retInt = b2[0] & 0xFF;
retInt <<= 8;
retInt += b2[1] & 0xFF;
return retInt;
}
static private long get32(RandomAccessFile f, long lgOffset) {
long retLong;
byte b4[] = new byte[4];
try {
if(lgOffset>0) {
f.seek(lgOffset);
}
f.read(b4);
}
catch(IOException e) {
System.out.println(e);
return(-1);
}
retLong = b4[0] & 0xFF;
retLong <<= 8;
retLong += b4[1] & 0xFF;
retLong <<= 8;
retLong += b4[2] & 0xFF;
retLong <<= 8;
retLong += b4[3] & 0xFF;
return retLong;
}
}
//以上、Java source code