org.jpedal.fonts.CIDType1CParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of OpenViewerFX Show documentation
Show all versions of OpenViewerFX Show documentation
Open Source (LGPL) JavaFX PDF Viewer for NetBeans plugin
The newest version!
/*
* ===========================================
* Java Pdf Extraction Decoding Access Library
* ===========================================
*
* Project Info: http://www.idrsolutions.com
* Help section for developers at http://www.idrsolutions.com/support/
*
* (C) Copyright 1997-2017 IDRsolutions and Contributors.
*
* This file is part of JPedal/JPDF2HTML5
*
@LICENSE@
*
* ---------------
* CIDType1CParser.java
* ---------------
*/
package org.jpedal.fonts;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
public class CIDType1CParser {
public static final String[] STANDARD_ENCODING = {
".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", "space", "exclam", "quotedbl",
"numbersign", "dollar", "percent", "ampersand",
"quoteright", "parenleft", "parenright", "asterisk", "plus",
"comma", "hyphen", "period", "slash", "zero", "one", "two",
"three", "four", "five", "six", "seven", "eight", "nine",
"colon", "semicolon", "less", "equal", "greater",
"question", "at", "A", "B", "C", "D", "E", "F", "G", "H",
"I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
"U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash",
"bracketright", "asciicircum", "underscore", "quoteleft",
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
"m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x",
"y", "z", "braceleft", "bar", "braceright", "asciitilde",
".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef", "exclamdown",
"cent", "sterling", "fraction", "yen", "florin", "section",
"currency", "quotesingle", "quotedblleft", "guillemotleft",
"guilsinglleft", "guilsinglright", "fi", "fl", ".notdef",
"endash", "dagger", "daggerdbl", "periodcentered",
".notdef", "paragraph", "bullet", "quotesinglbase",
"quotedblbase", "quotedblright", "guillemotright",
"ellipsis", "perthousand", ".notdef", "questiondown",
".notdef", "grave", "acute", "circumflex", "tilde",
"macron", "breve", "dotaccent", "dieresis", ".notdef",
"ring", "cedilla", ".notdef", "hungarumlaut", "ogonek",
"caron", "emdash", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", "AE", ".notdef",
"ordfeminine", ".notdef", ".notdef", ".notdef", ".notdef",
"Lslash", "Oslash", "OE", "ordmasculine", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef", "ae", ".notdef",
".notdef", ".notdef", "dotlessi", ".notdef", ".notdef",
"lslash", "oslash", "oe", "germandbls", ".notdef",
".notdef", ".notdef", ".notdef"
};
public static final String[] EXPERT_ENCODING = {
".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", "space", "exclamsmall", "Hungarumlautsmall",
".notdef", "dollaroldstyle", "dollarsuperior", "ampersandsmall",
"Acutesmall", "parenleftsuperior", "parenrightsuperior", "twodotenleader",
"onedotenleader", "comma",
"hyphen", "period", "fraction", "zerooldstyle", "oneoldstyle",
"twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle",
"sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "colon",
"semicolon", "commasuperior", "threequartersemdash", "periodsuperior",
"questionsmall", ".notdef", "asuperior", "bsuperior", "centsuperior",
"dsuperior", "esuperior", ".notdef", ".notdef", "isuperior", ".notdef",
".notdef", "lsuperior", "msuperior", "nsuperior", "osuperior", ".notdef",
".notdef", "rsuperior", "ssuperior", "tsuperior",
".notdef", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior", ".notdef",
"parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall",
"Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall",
"Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall",
"Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall",
"Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary",
"onefitted", "rupiah", "Tildesmall", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
".notdef", "exclamdownsmall", "centoldstyle", "Lslashsmall", ".notdef",
".notdef", "Scaronsmall", "Zcaronsmall", "Dieresissmall", "Brevesmall",
"Caronsmall", ".notdef", "Dotaccentsmall", ".notdef", ".notdef",
"Macronsmall", ".notdef", ".notdef", "figuredash", "hypheninferior",
".notdef", ".notdef", "Ogoneksmall", "Ringsmall",
"Cedillasmall", ".notdef", ".notdef", ".notdef", "onequarter", "onehalf",
"threequarters", "questiondownsmall", "oneeighth", "threeeighths", "fiveeighths",
"seveneighths", "onethird", "twothirds", ".notdef", ".notdef", "zerosuperior",
"onesuperior", "twosuperior", "threesuperior", "foursuperior",
"fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior",
"ninesuperior", "zeroinferior", "oneinferior", "twoinferior",
"threeinferior", "fourinferior", "fiveinferior", "sixinferior",
"seveninferior", "eightinferior", "nineinferior", "centinferior",
"dollarinferior", "periodinferior", "commainferior", "Agravesmall",
"Aacutesmall", "Acircumflexsmall", "Atildesmall", "Adieresissmall",
"Aringsmall", "AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall",
"Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall",
"Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall",
"Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall",
"Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall",
"Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall",
"Ydieresissmall"
};
public static final String[] MACROMAN_STANDARD_ENCODING = {
"NUL", "Eth", "eth", "Lslash", "lslash", "Scaron", "scaron", "Yacute",
"yacute", "HT", "LF", "Thorn", "thorn", "CR", "Zcaron", "zcaron", "DLE", "DC1",
"DC2", "DC3", "DC4", "onehalf", "onequarter", "onesuperior", "threequarters",
"threesuperior", "twosuperior", "brokenbar", "minus", "multiply", "RS", "US",
"space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand",
"quotesingle", "parenleft", "parenright", "asterisk", "plus", "comma",
"hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five",
"six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal",
"greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
"K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
"bracketleft", "backslash", "bracketright", "asciicircum", "underscore",
"grave", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",
"o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar",
"braceright", "asciitilde", "DEL", "Adieresis", "Aring", "Ccedilla", "Eacute",
"Ntilde", "Odieresis", "Udieresis", "aacute", "agrave", "acircumflex",
"adieresis", "atilde", "aring", "ccedilla", "eacute", "egrave", "ecircumflex",
"edieresis", "iacute", "igrave", "icircumflex", "idieresis", "ntilde",
"oacute", "ograve", "ocircumflex", "odieresis", "otilde", "uacute", "ugrave",
"ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling", "section",
"bullet", "paragraph", "germandbls", "registered", "copyright", "trademark",
"acute", "dieresis", "notequal", "AE", "Oslash", "infinity", "plusminus",
"lessequal", "greaterequal", "yen", "mu", "partialdiff", "summation",
"product", "pi", "integral", "ordfeminine", "ordmasculine", "Omega", "ae",
"oslash", "questiondown", "exclamdown", "logicalnot", "radical", "florin",
"approxequal", "Delta", "guillemotleft", "guillemotright", "ellipsis",
"nbspace", "Agrave", "Atilde", "Otilde", "OE", "oe", "endash", "emdash",
"quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", "lozenge",
"ydieresis", "Ydieresis", "fraction", "currency", "guilsinglleft",
"guilsinglright", "fi", "fl", "daggerdbl", "periodcentered", "quotesinglbase",
"quotedblbase", "perthousand", "Acircumflex", "Ecircumflex", "Aacute",
"Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave", "Oacute",
"Ocircumflex", "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", "dotlessi",
"circumflex", "tilde", "macron", "breve", "dotaccent", "ring", "cedilla",
"hungarumlaut", "ogonek", "caron"
};
// The 391 Standard Strings as used in the CFF format. [Adobe Technical None #5176]
public static final String[] CFF_STANDARD_STRINGS = {
".notdef", "space", "exclam", "quotedbl", "numbersign",
"dollar", "percent", "ampersand", "quoteright", "parenleft", "parenright",
"asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one",
"two", "three", "four", "five", "six", "seven", "eight", "nine", "colon",
"semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C",
"D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
"S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash",
"bracketright", "asciicircum", "underscore", "quoteleft", "a", "b", "c",
"d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r",
"s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright",
"asciitilde", "exclamdown", "cent", "sterling", "fraction", "yen", "florin",
"section", "currency", "quotesingle", "quotedblleft", "guillemotleft",
"guilsinglleft", "guilsinglright", "fi", "fl", "endash", "dagger",
"daggerdbl", "periodcentered", "paragraph", "bullet", "quotesinglbase",
"quotedblbase", "quotedblright", "guillemotright", "ellipsis", "perthousand",
"questiondown", "grave", "acute", "circumflex", "tilde", "macron", "breve",
"dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut", "ogonek", "caron",
"emdash", "AE", "ordfeminine", "Lslash", "Oslash", "OE", "ordmasculine", "ae",
"dotlessi", "lslash", "oslash", "oe", "germandbls", "onesuperior",
"logicalnot", "mu", "trademark", "Eth", "onehalf", "plusminus", "Thorn",
"onequarter", "divide", "brokenbar", "degree", "thorn", "threequarters",
"twosuperior", "registered", "minus", "eth", "multiply", "threesuperior",
"copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave", "Aring",
"Atilde", "Ccedilla", "Eacute", "Ecircumflex", "Edieresis", "Egrave",
"Iacute", "Icircumflex", "Idieresis", "Igrave", "Ntilde", "Oacute",
"Ocircumflex", "Odieresis", "Ograve", "Otilde", "Scaron", "Uacute",
"Ucircumflex", "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron",
"aacute", "acircumflex", "adieresis", "agrave", "aring", "atilde", "ccedilla",
"eacute", "ecircumflex", "edieresis", "egrave", "iacute", "icircumflex",
"idieresis", "igrave", "ntilde", "oacute", "ocircumflex", "odieresis",
"ograve", "otilde", "scaron", "uacute", "ucircumflex", "udieresis", "ugrave",
"yacute", "ydieresis", "zcaron", "exclamsmall", "Hungarumlautsmall",
"dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall",
"parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader",
"zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle",
"fiveoldstyle", "sixoldstyle", "sevenoldstyle", "eightoldstyle",
"nineoldstyle", "commasuperior", "threequartersemdash", "periodsuperior",
"questionsmall", "asuperior", "bsuperior", "centsuperior", "dsuperior",
"esuperior", "isuperior", "lsuperior", "msuperior", "nsuperior", "osuperior",
"rsuperior", "ssuperior", "tsuperior", "ff", "ffi", "ffl", "parenleftinferior",
"parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall",
"Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", "Hsmall",
"Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall",
"Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall", "Xsmall",
"Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah", "Tildesmall",
"exclamdownsmall", "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall",
"Dieresissmall", "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall",
"figuredash", "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall",
"questiondownsmall", "oneeighth", "threeeighths", "fiveeighths", "seveneighths",
"onethird", "twothirds", "zerosuperior", "foursuperior", "fivesuperior",
"sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior",
"oneinferior", "twoinferior", "threeinferior", "fourinferior", "fiveinferior",
"sixinferior", "seveninferior", "eightinferior", "nineinferior", "centinferior",
"dollarinferior", "periodinferior", "commainferior", "Agravesmall",
"Aacutesmall", "Acircumflexsmall", "Atildesmall", "Adieresissmall", "Aringsmall",
"AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall", "Ecircumflexsmall",
"Edieresissmall", "Igravesmall", "Iacutesmall", "Icircumflexsmall",
"Idieresissmall", "Ethsmall", "Ntildesmall", "Ogravesmall", "Oacutesmall",
"Ocircumflexsmall", "Otildesmall", "Odieresissmall", "OEsmall", "Oslashsmall",
"Ugravesmall", "Uacutesmall", "Ucircumflexsmall", "Udieresissmall",
"Yacutesmall", "Thornsmall", "Ydieresissmall", "001.000", "001.001", "001.002",
"001.003", "Black", "Bold", "Book", "Light", "Medium", "Regular", "Roman",
"Semibold"
};
public static final int CFF_STANDARD_STRING_COUNT = 391;
public static final HashMap CFF_STANDARD_STRING_MAP = new HashMap();
static {
for (int i = 0; i < 391; i++) {
CFF_STANDARD_STRING_MAP.put(CFF_STANDARD_STRINGS[i], i);
}
}
public static final String[] CFF_ISO_ADOBE_STRINGS = {
".notdef", "space", "exclam", "quotedbl", "numbersign",
"dollar", "percent", "ampersand", "quoteright", "parenleft", "parenright",
"asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two",
"three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon",
"less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G",
"H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W",
"X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum",
"underscore", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
"k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
"braceleft", "bar", "braceright", "asciitilde", "exclamdown", "cent",
"sterling", "fraction", "yen", "florin", "section", "currency", "quotesingle",
"quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", "fl",
"endash", "dagger", "daggerdbl", "periodcentered", "paragraph", "bullet",
"quotesinglbase", "quotedblbase", "quotedblright", "guillemotright", "ellipsis",
"perthousand", "questiondown", "grave", "acute", "circumflex", "tilde",
"macron", "breve", "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut",
"ogonek", "caron", "emdash", "AE", "ordfeminine", "Lslash", "Oslash", "OE",
"ordmasculine", "ae", "dotlessi", "lslash", "oslash", "oe", "germandbls",
"onesuperior", "logicalnot", "mu", "trademark", "Eth", "onehalf", "plusminus",
"Thorn", "onequarter", "divide", "brokenbar", "degree", "thorn",
"threequarters", "twosuperior", "registered", "minus", "eth", "multiply",
"threesuperior", "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave",
"Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex", "Edieresis", "Egrave",
"Iacute", "Icircumflex", "Idieresis", "Igrave", "Ntilde", "Oacute",
"Ocircumflex", "Odieresis", "Ograve", "Otilde", "Scaron", "Uacute",
"Ucircumflex", "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron", "aacute",
"acircumflex", "adieresis", "agrave", "aring", "atilde", "ccedilla", "eacute",
"ecircumflex", "edieresis", "egrave", "iacute", "icircumflex", "idieresis",
"igrave", "ntilde", "oacute", "ocircumflex", "odieresis", "ograve", "otilde",
"scaron", "uacute", "ucircumflex", "udieresis", "ugrave", "yacute", "ydieresis",
"zcaron"
};
public static final int CFF_ISO_ADOBE_STRING_COUNT = 229;
public static final String[] CFF_EXPERT_STRINGS = {
".notdef", "space", "exclamsmall", "Hungarumlautsmall",
"dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall",
"parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader",
"comma", "hyphen", "period", "fraction", "zerooldstyle", "oneoldstyle",
"twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle",
"sevenoldstyle", "eightoldstyle", "nineoldstyle", "colon", "semicolon",
"commasuperior", "threequartersemdash", "periodsuperior", "questionsmall",
"asuperior", "bsuperior", "centsuperior", "dsuperior", "esuperior", "isuperior",
"lsuperior", "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior",
"tsuperior", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior",
"parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall",
"Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", "Hsmall",
"Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall",
"Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall", "Xsmall",
"Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah", "Tildesmall",
"exclamdownsmall", "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall",
"Dieresissmall", "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall",
"figuredash", "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall",
"onequarter", "onehalf", "threequarters", "questiondownsmall", "oneeighth",
"threeeighths", "fiveeighths", "seveneighths", "onethird", "twothirds",
"zerosuperior", "onesuperior", "twosuperior", "threesuperior", "foursuperior",
"fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior",
"zeroinferior", "oneinferior", "twoinferior", "threeinferior", "fourinferior",
"fiveinferior", "sixinferior", "seveninferior", "eightinferior", "nineinferior",
"centinferior", "dollarinferior", "periodinferior", "commainferior",
"Agravesmall", "Aacutesmall", "Acircumflexsmall", "Atildesmall",
"Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall", "Egravesmall",
"Eacutesmall", "Ecircumflexsmall", "Edieresissmall", "Igravesmall",
"Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall",
"Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall",
"Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall",
"Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall",
"Ydieresissmall"
};
public static final int CFF_EXPERT_STRING_COUNT = 166;
public static final String[] CFF_EXPERT_SUBSET_STRINGS = {
".notdef", "space", "dollaroldstyle",
"dollarsuperior", "parenleftsuperior", "parenrightsuperior", "twodotenleader",
"onedotenleader", "comma", "hyphen", "period", "fraction", "zerooldstyle",
"oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle",
"sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "colon",
"semicolon", "commasuperior", "threequartersemdash", "periodsuperior",
"asuperior", "bsuperior", "centsuperior", "dsuperior", "esuperior", "isuperior",
"lsuperior", "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior",
"tsuperior", "ff", "fi", "fl", "ffi", "ffl", "parenleftinferior",
"parenrightinferior", "hyphensuperior", "colonmonetary", "onefitted", "rupiah",
"centoldstyle", "figuredash", "hypheninferior", "onequarter", "onehalf",
"threequarters", "oneeighth", "threeeighths", "fiveeighths", "seveneighths",
"onethird", "twothirds", "zerosuperior", "onesuperior", "twosuperior",
"threesuperior", "foursuperior", "fivesuperior", "sixsuperior", "sevensuperior",
"eightsuperior", "ninesuperior", "zeroinferior", "oneinferior", "twoinferior",
"threeinferior", "fourinferior", "fiveinferior", "sixinferior", "seveninferior",
"eightinferior", "nineinferior", "centinferior", "dollarinferior",
"periodinferior", "commainferior"
};
public static final int CFF_EXPERT_SUBSET_STRING_COUNT = 87;
//one byte operators
public static final int VERSION = 0;
public static final int NOTICE = 1;
public static final int FULLNAME = 2;
public static final int FAMILYNAME = 3;
public static final int WEIGHT = 4;
public static final int FONTBBOX = 5;
public static final int BLUEVALUES = 6;
public static final int OTHERBLUES = 7;
public static final int FAMILYBLUES = 8;
public static final int FAMILYOTHERBLUES = 9;
public static final int STDHW = 10;
public static final int STDVW = 11;
public static final int ESCAPE = 12;
public static final int UNIQUEID = 13;
public static final int XUID = 14;
public static final int CHARSET = 15;
public static final int ENCODING = 16;
public static final int CHARSTRINGS = 17;
public static final int PRIVATE = 18;
public static final int SUBRS = 19;
public static final int DEFAULTWIDTHX = 20;
public static final int NOMINALWIDTHX = 21;
public static final int RESERVED = 22;
public static final int SHORTINT = 28;
public static final int LONGINT = 29;
public static final int BCD = 30;
//two byte operators
public static final int COPYRIGHT = 3072;
public static final int ISFIXEDPITCH = 3073;
public static final int ITALICANGLE = 3074;
public static final int UNDERLINEPOSITION = 3075;
public static final int UNDERLINETHICKNESS = 3076;
public static final int PAINTTYPE = 3077;
public static final int CHARSTRINGTYPE = 3078;
public static final int FONTMATRIX = 3079;
public static final int STROKEWIDTH = 3080;
public static final int BLUESCALE = 3081;
public static final int BLUESHIFT = 3082;
public static final int BLUEFUZZ = 3083;
public static final int STEMSNAPH = 3084;
public static final int STEMSNAPV = 3085;
public static final int FORCEBOLD = 3086;
public static final int LANGUAGEGROUP = 3089;
public static final int EXPANSIONFACTOR = 3090;
public static final int INITIALRANDOMSEED = 3091;
public static final int SYNTHETICBASE = 3092;
public static final int POSTSCRIPT = 3093;
public static final int BASEFONTNAME = 3094;
public static final int BASEFONTBLEND = 3095;
public static final int ROS = 3102;
public static final int CIDFONTVERSION = 3103;
public static final int CIDFONTREVISION = 3104;
public static final int CIDFONTTYPE = 3105;
public static final int CIDCOUNT = 3106;
public static final int UIDBASE = 3107;
public static final int FDARRAY = 3108;
public static final int FDSELECT = 3109;
public static final int FONTNAME = 3110;
public static final int TYPE_NUMBER = 0;
public static final int TYPE_ARRAY = 1;
public static final int TYPE_DELTA = 2;
public static final int TYPE_SID = 3;
public static final int TYPE_PRIVATE = 4;
public static final int TYPE_ROS = 5;
public static final int CHARSET_TYPE_ISO_ADOBE = 0;
public static final int CHARSET_TYPE_EXPERT = 1;
public static final int CHARSET_TYPE_EXPERTSUBSET = 2;
public static final CCSV[] CS_VALIDATION1 = new CCSV[32];
public static final CCSV[] CS_VALIDATION2 = new CCSV[40];
static {
CS_VALIDATION1[0] = null;
CS_VALIDATION1[1] = new CCSV("hstem", 2, true, false, false, true, null, false);
CS_VALIDATION1[2] = null;
CS_VALIDATION1[3] = new CCSV("vstem", 2, true, false, false, true, null, false);
CS_VALIDATION1[4] = new CCSV("vmoveto", 1, true, false, false, false, null, false);
CS_VALIDATION1[5] = new CCSV("rlineto", 2, false, true, false, false, null, false);
CS_VALIDATION1[6] = new CCSV("hlineto", 1, false, true, false, false, null, false);
CS_VALIDATION1[7] = new CCSV("vlineto", 1, false, true, false, false, null, false);
CS_VALIDATION1[8] = new CCSV("rrcurveto", 6, false, true, false, false, null, false);
CS_VALIDATION1[9] = null;
CS_VALIDATION1[10] = new CCSV("callsubr", 1, false, false, true, false, null, false);
CS_VALIDATION1[11] = new CCSV("return", 0, false, false, true, false, null, false);
CS_VALIDATION1[12] = null;
CS_VALIDATION1[13] = null;
CS_VALIDATION1[14] = new CCSV("endchar", 0, true, false, false, false, null, false);
CS_VALIDATION1[15] = null;
CS_VALIDATION1[16] = null;
CS_VALIDATION1[17] = null;
CS_VALIDATION1[18] = new CCSV("hstemhm", 2, true, false, false, true, null, false);
CS_VALIDATION1[19] = new CCSV("hintmask", 0, true, false, false, false, null, false);
CS_VALIDATION1[20] = new CCSV("cntrmask", 0, true, false, false, false, null, false);
CS_VALIDATION1[21] = new CCSV("rmoveto", 2, true, false, false, false, null, false);
CS_VALIDATION1[22] = new CCSV("hmoveto", 1, true, false, false, false, null, false);
CS_VALIDATION1[23] = new CCSV("vstemhm", 2, true, false, false, true, null, false);
CS_VALIDATION1[24] = new CCSV("rcurveline", 8, false, true, false, false, null, false);
CS_VALIDATION1[25] = new CCSV("rlinecurve", 8, false, true, false, false, null, false);
CS_VALIDATION1[26] = new CCSV("vvcurveto", 4, false, true, false, false, null, false);
CS_VALIDATION1[27] = new CCSV("hhcurveto", 4, false, true, false, false, null, false);
CS_VALIDATION1[28] = null;
CS_VALIDATION1[29] = new CCSV("callgsubr", 1, false, false, true, false, null, false);
CS_VALIDATION1[30] = new CCSV("vhcurveto", 4, false, true, false, false, null, false);
CS_VALIDATION1[31] = new CCSV("hvcurveto", 4, false, true, false, false, null, false);
CS_VALIDATION2[0] = null;
CS_VALIDATION2[1] = null;
CS_VALIDATION2[2] = null;
CS_VALIDATION2[4] = new CCSV("and", 2, false, false, false, false, -1, false);
CS_VALIDATION2[5] = new CCSV("or", 2, false, false, false, false, -1, false);
CS_VALIDATION2[6] = new CCSV("not", 1, false, false, false, false, 0, false);
CS_VALIDATION2[7] = null;
CS_VALIDATION2[8] = null;
CS_VALIDATION2[9] = null;
CS_VALIDATION2[10] = new CCSV("abs", 1, false, false, false, false, 0, false);
CS_VALIDATION2[11] = new CCSV("add", 2, false, false, false, false, -1, true);
CS_VALIDATION2[12] = new CCSV("sub", 2, false, false, false, false, -1, true);
CS_VALIDATION2[13] = new CCSV("div", 2, false, false, false, false, -1, true);
CS_VALIDATION2[14] = null;
CS_VALIDATION2[15] = new CCSV("neg", 1, false, false, false, false, 0, true);
CS_VALIDATION2[16] = new CCSV("eq", 2, false, false, false, false, -1, false);
CS_VALIDATION2[17] = null;
CS_VALIDATION2[18] = null;
CS_VALIDATION2[19] = new CCSV("drop", 1, false, false, false, false, -1, false);
CS_VALIDATION2[20] = null;
CS_VALIDATION2[21] = null;
CS_VALIDATION2[22] = new CCSV("put", 2, false, false, false, false, -2, false);
CS_VALIDATION2[23] = new CCSV("get", 1, false, false, false, false, 0, false);
CS_VALIDATION2[24] = new CCSV("ifelse", 4, false, false, false, false, -3, false);
CS_VALIDATION2[25] = new CCSV("random", 0, false, false, false, false, 1, false);
CS_VALIDATION2[26] = new CCSV("mul", 2, false, false, false, false, -1, true);
CS_VALIDATION2[27] = null;
CS_VALIDATION2[28] = new CCSV("sqrt", 1, false, false, false, false, 0, false);
CS_VALIDATION2[29] = new CCSV("dub", 1, false, false, false, false, 1, false);
CS_VALIDATION2[30] = new CCSV("exch", 2, false, false, false, false, 0, false);
CS_VALIDATION2[31] = new CCSV("index", 2, false, false, false, false, 0, false);
CS_VALIDATION2[32] = new CCSV("roll", 3, false, false, false, false, -2, false);
CS_VALIDATION2[33] = null;
CS_VALIDATION2[34] = null;
CS_VALIDATION2[35] = null;
CS_VALIDATION2[36] = new CCSV("hflex", 7, false, true, false, false, null, false);
CS_VALIDATION2[37] = new CCSV("flex", 13, false, true, false, false, null, false);
CS_VALIDATION2[38] = new CCSV("hflex1", 9, false, true, false, false, null, false);
CS_VALIDATION2[39] = new CCSV("flex1", 11, false, true, false, false, null, false);
}
public static boolean debug = true;
public static CIDType1C parse(final FileInput fb) throws IOException {
final CIDType1C font = new CIDType1C();
// reading header
font.headerMajor = fb.getU8();
font.headerMinor = fb.getU8();
font.headerSize = fb.getU8();
font.headerOffsize = fb.getU8();
final int[] nameIndex = parseIndex(fb, font.headerSize);
font.nameIndexData = indexToStringArray(fb, nameIndex);
final int[] topDictIndex = parseIndex(fb, nameIndex[nameIndex.length - 1]);
font.topDicts = parseDict(fb, topDictIndex);
final int[] stringIndex = parseIndex(fb, topDictIndex[topDictIndex.length - 1]);
font.stringIndexData = indexToStringArray(fb, stringIndex);
final int[] globalSubrIndex = parseIndex(fb, stringIndex[stringIndex.length - 1]);
font.globalSubrsIndexData = indexToByteArray(fb, globalSubrIndex);
for (final Dict dict : font.topDicts) {
final boolean isCID = dict.entries.containsKey(ROS);
// update private dictionary
dict.privateDict = parsePrivateDict(fb, dict);
// update ascent, descent
Number[] values = dict.entries.get(FONTBBOX);
if (values != null && values.length == 4) {
dict.ascent = Math.max(values[3].intValue(), values[1].intValue());
dict.descent = Math.min(values[1].intValue(), values[3].intValue());
}
// update charstring index
values = dict.entries.get(CHARSTRINGS);
if (values != null) {
final int charStringOffset = values[0].intValue();
final int[] charStringIndex = parseIndex(fb, charStringOffset);
font.charStringIndexData = indexToByteArray(fb, charStringIndex);
// update charsets
values = dict.entries.get(CHARSET);
dict.charset = parseCharset(fb, values, charStringIndex.length - 1, font.stringIndexData, isCID);
}
// update encoding and remove encodings for CID
if (isCID) {
dict.entries.remove(ENCODING);
Number[] fVal = dict.entries.get(FDARRAY);
final int[] fdArrayIndex = parseIndex(fb, fVal[0].intValue());
final byte[][] fdArrayIndexData = indexToByteArray(fb, fdArrayIndex);
final int fdArrLen = fdArrayIndexData.length;
dict.fontDicts = new Dict[fdArrLen];
for (int i = 0; i < fdArrLen; i++) {
dict.fontDicts[i] = new Dict(fdArrayIndexData[i]);
dict.fontDicts[i].privateDict = parsePrivateDict(fb, dict.fontDicts[i]);
}
fVal = dict.entries.get(FDSELECT);
dict.fdSelect = parseFDSelect(fb, fVal, font.charStringIndexData.length);
} else {
values = dict.entries.get(ENCODING);
dict.encoding = parseEncoding(fb, values, dict.charset.charset);
}
final byte[][] localSubrsIndexData = dict.privateDict != null ? dict.privateDict.subrsIndexData : null;
parseCharStrings(dict, font.charStringIndexData, font.globalSubrsIndexData, localSubrsIndexData);
font.glyphWidths = new int[font.charStringIndexData.length][1];
updateWidthsNormal(font.charStringIndexData, font.glyphWidths, dict);
}
// now print dict
if (debug) {
System.out.println("printing Name Index .....................");
for (final String string : font.nameIndexData) {
System.out.println(string);
}
for (final Dict dict : font.topDicts) {
System.out.println("printing Dictionary Normal Values.....................");
for (final Integer entryKey : dict.entries.keySet()) {
final Number[] values = dict.entries.get(entryKey);
printDictEntry(entryKey, values);
if (getKeyType(entryKey) == TYPE_SID) {
System.out.println("sid : " + getFromStringIndexData(font.stringIndexData, values[0].intValue()));
}
}
if (dict.privateDict != null) {
System.out.println("-------- private Dictionary All Values------------");
for (final Integer entryKey : dict.privateDict.entries.keySet()) {
final Number[] vv = dict.privateDict.entries.get(entryKey);
printDictEntry(entryKey, vv);
if (getKeyType(entryKey) == TYPE_SID) {
System.out.println("\tsid : " + getFromStringIndexData(font.stringIndexData, vv[0].intValue()));
}
}
System.out.println("--------------------------------------------------");
}
final Number[] rosValues = dict.entries.get(ROS);
if (rosValues != null) {
System.out.println("---------- printing FDSelect --------------------");
System.out.println("\n--------------------------------------------------");
} else {
System.out.println("---------- printing Encodings --------------------");
System.out.println("encoding array : " + dict.encoding.format);
final int[] encodings = dict.encoding.encoding;
for (int i = 0; i < encodings.length; i++) {
if (encodings[i] != -1) {
System.out.print(" enc : " + encodings[i]);
}
}
System.out.println("\n--------------------------------------------------");
}
System.out.println("----------- printing Widths ----------------------");
if (debug) {
for (int i = 0; i < font.glyphWidths.length; i++) {
System.out.println(i + " width : " + font.glyphWidths[i][0]);
}
}
System.out.println("--------------------------------------------------");
final boolean isCID = dict.entries.containsKey(ROS);
if (isCID) {
System.out.println("-------- printing cid Fontdict Values------------");
for (final Dict fontDict : dict.fontDicts) {
for (final Integer entryKey : fontDict.entries.keySet()) {
final Number[] values = fontDict.entries.get(entryKey);
printDictEntry(entryKey, values);
if (getKeyType(entryKey) == TYPE_SID) {
System.out.println("sid : " + getFromStringIndexData(font.stringIndexData, values[0].intValue()));
}
}
}
System.out.println("--------------------------------------------------");
}
}
System.out.println("GlobalSubrIndex : " + globalSubrIndex.length);
}
fb.close();
// Index nameIndex = new Index();
// reading name index
return font;
}
public static byte[] fix(final CIDType1C font, final String customName) throws IOException {
changeFontName(font, customName);
// write header
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write(font.headerMajor);
bos.write(font.headerMinor);
bos.write(4);
bos.write(font.headerOffsize);
// write name index
bos.write(createIndex(font.nameIndexData));
// write TOPDict
final Dict firstTop = font.topDicts[0];
final byte[] dictBytes = createDictBytes(firstTop);
final Dict t = new Dict(dictBytes);
System.out.println("printing Dictionary Normal Values.....................");
for (final Integer entryKey : t.entries.keySet()) {
final Number[] values = t.entries.get(entryKey);
printDictEntry(entryKey, values);
if (getKeyType(entryKey) == TYPE_SID) {
System.out.println("sid : " + getFromStringIndexData(font.stringIndexData, values[0].intValue()));
}
}
bos.write(createIndex(font.stringIndexData));
bos.write(createIndex(font.globalSubrsIndexData));
return bos.toByteArray();
}
private static void changeFontName(final CIDType1C font, final String customName) {
font.nameIndexData = new String[]{customName};
final Dict firstTop = font.topDicts[0];
final String[] temp = new String[font.stringIndexData.length + 1];
System.arraycopy(font.stringIndexData, 0, temp, 0, temp.length - 1);
temp[temp.length - 1] = customName;
font.stringIndexData = temp;
firstTop.entries.put(FULLNAME, new Number[]{390 + temp.length});
firstTop.entries.put(FAMILYNAME, new Number[]{390 + temp.length});
firstTop.entries.put(BASEFONTNAME, new Number[]{390 + temp.length});
}
private static byte[] createDictBytes(final Dict dict) throws IOException {
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
for (final Integer key : dict.entries.keySet()) {
final Number[] values = dict.entries.get(key);
switch (key) {
case CHARSET:
case ENCODING:
case CHARSTRINGS:
case PRIVATE:
case FDARRAY:
case FDSELECT:
case SUBRS:
dict.trackers.put(key, bos.size());
final byte[] tt = new byte[5];
tt[0] = 0x1d;
bos.write(tt);
break;
default:
for (final Number value : values) {
if (value.intValue() == value.floatValue()) {
final byte[] temp = encodeInt(value.intValue());
bos.write(temp);
} else {
final byte[] temp = encodeFloat(value.floatValue());
bos.write(temp);
}
}
}
if (key < 3000) {
bos.write(key);
} else {
final int b1 = (key >> 8) & 0xff;
final int b2 = key & 0xff;
bos.write(b1);
bos.write(b2);
}
}
return bos.toByteArray();
}
private static byte[] createIndex(final String[] strArr) throws IOException {
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
if (strArr == null || strArr.length == 0) {
return new byte[]{0, 0, 0};
}
final int sLen = strArr.length;
bos.write((sLen >> 8) & 0xff);
bos.write(sLen & 0xff);
int lastOffset = 1;
for (int i = 0; i < sLen; ++i) {
lastOffset += strArr[i].length();
}
final int offsetSize;
if (lastOffset < 0x100) {
offsetSize = 1;
} else if (lastOffset < 0x10000) {
offsetSize = 2;
} else if (lastOffset < 0x1000000) {
offsetSize = 3;
} else {
offsetSize = 4;
}
bos.write(offsetSize);
int relativeOffset = 1;
for (int i = 0; i < sLen + 1; i++) {
switch (offsetSize) {
case 1:
bos.write(relativeOffset & 0xFF);
break;
case 2:
bos.write((relativeOffset >> 8) & 0xFF);
bos.write(relativeOffset & 0xFF);
break;
case 3:
bos.write((relativeOffset >> 16) & 0xFF);
bos.write((relativeOffset >> 8) & 0xFF);
bos.write(relativeOffset & 0xFF);
break;
default:
bos.write((relativeOffset >>> 24) & 0xFF);
bos.write((relativeOffset >> 16) & 0xFF);
bos.write((relativeOffset >> 8) & 0xFF);
bos.write(relativeOffset & 0xFF);
break;
}
if (i < sLen) {
relativeOffset += strArr[i].length();
}
}
for (final String str : strArr) {
bos.write(str.getBytes());
}
return bos.toByteArray();
}
private static byte[] createIndex(final byte[][] byteArr) throws IOException {
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
if (byteArr == null || byteArr.length == 0) {
return new byte[]{0, 0, 0};
}
final int arrLen = byteArr.length;
bos.write((arrLen >> 8) & 0xff);
bos.write(arrLen & 0xff);
int lastOffset = 1;
for (int i = 0; i < arrLen; ++i) {
lastOffset += byteArr[i].length;
}
final int offsetSize;
if (lastOffset < 0x100) {
offsetSize = 1;
} else if (lastOffset < 0x10000) {
offsetSize = 2;
} else if (lastOffset < 0x1000000) {
offsetSize = 3;
} else {
offsetSize = 4;
}
bos.write(offsetSize);
int relativeOffset = 1;
for (int i = 0; i < arrLen + 1; i++) {
switch (offsetSize) {
case 1:
bos.write(relativeOffset & 0xFF);
break;
case 2:
bos.write((relativeOffset >> 8) & 0xFF);
bos.write(relativeOffset & 0xFF);
break;
case 3:
bos.write((relativeOffset >> 16) & 0xFF);
bos.write((relativeOffset >> 8) & 0xFF);
bos.write(relativeOffset & 0xFF);
break;
default:
bos.write((relativeOffset >>> 24) & 0xFF);
bos.write((relativeOffset >> 16) & 0xFF);
bos.write((relativeOffset >> 8) & 0xFF);
bos.write(relativeOffset & 0xFF);
break;
}
if (i < arrLen) {
relativeOffset += byteArr[i].length;
}
}
for (int i = 0; i < arrLen; i++) {
bos.write(byteArr[i]);
}
return bos.toByteArray();
}
private static String getFromStringIndexData(final String[] arr, final int sid) {
if (sid >= 0 && sid <= 390) {
return CFF_STANDARD_STRINGS[sid];
}
final int gap = sid - 391;
if ((sid - 391) <= (arr.length - 1)) {
return arr[gap];
} else {
return CFF_STANDARD_STRINGS[0];
}
}
private static int[] parseIndex(final FileInput fb, final int indexOffset) throws IOException {
fb.moveTo(indexOffset);
final int count = fb.getU16();
final int end = fb.getPosition();
int[] results = {end};
if (count != 0) {
final int offSize = fb.getU8();
results = new int[count + 1];
final int startPos = fb.getPosition() + ((count + 1) * offSize) - 1;
for (int i = 0, ii = count + 1; i < ii; ++i) {
final int offset = fb.getOffset(offSize);
results[i] = (startPos + offset);
}
}
return results;
}
private static Dict parsePrivateDict(final FileInput fb, final Dict dict) throws IOException {
final Number[] values = dict.entries.get(PRIVATE);
if (values != null && values.length > 1) {
final int len = values[0].intValue();
final int offset = values[1].intValue();
if (len > 0) {
final byte[] temp = new byte[len];
fb.moveTo(offset);
fb.read(temp);
final Dict privateDict = new Dict(temp);
final Number[] subrsValues = privateDict.entries.get(SUBRS);
if (subrsValues != null) {
final int subrOffset = subrsValues[0].intValue();
if (subrOffset != 0) {
final int[] indexes = parseIndex(fb, subrOffset + offset);
privateDict.subrsIndexData = indexToByteArray(fb, indexes);
}
}
return privateDict;
} else {
dict.entries.remove(PRIVATE);
}
}
return null;
}
private static void parseCharStrings(final Dict dict, final byte[][] charStringIndexData, final byte[][] globalSubrsIndexData, final byte[][] localSubrsIndexData) {
final double[] widths = new double[charStringIndexData.length];
final double[][] seacs = new double[charStringIndexData.length][];
for (int i = 0, ii = charStringIndexData.length; i < ii; i++) {
final CIDState state = new CIDState();
boolean valid = true;
byte[][] localSubrToUse = null;
if (dict.fdSelect != null && dict.fontDicts != null) {
final int fdIndex = dict.fdSelect.getFDIndex(i);
if (fdIndex == -1) {
valid = false;
}
if (fdIndex >= dict.fontDicts.length) {
valid = false;
}
if (valid) {
localSubrToUse = dict.fontDicts[fdIndex].privateDict.subrsIndexData;
}
} else if (localSubrsIndexData != null) {
localSubrToUse = localSubrsIndexData;
}
if (valid) {
valid = parseCharString(state, charStringIndexData[i], localSubrToUse, globalSubrsIndexData);
}
if (state.width != null) {
widths[i] = state.width;
}
if (state.seac != null) {
seacs[i] = state.seac;
}
if (!valid) {
charStringIndexData[i] = new byte[14];
}
}
}
private static void updateWidthsNormal(final byte[][] charStringIndexData, final int[][] glyphWidths, final Dict dict) {
int defaultWidthX = 0;
int nominalWidthX = 0;
if (dict.privateDict != null) {
Number[] values = dict.privateDict.entries.get(DEFAULTWIDTHX);
if (values != null) {
defaultWidthX = values[0].intValue();
}
values = dict.privateDict.entries.get(NOMINALWIDTHX);
if (values != null) {
nominalWidthX = values[0].intValue();
}
}
for (int i = 0, ii = charStringIndexData.length; i < ii; i++) {
final Integer ww = findWidth(charStringIndexData[i]);
glyphWidths[i][0] = ww == null ? defaultWidthX : ww + nominalWidthX;
}
}
// private static void updateWidthsCID(byte[][] charStringIndexData, int[][] glyphWidths, Dict fontDict) {
//
// }
private static Integer findWidth(final byte[] data) {
int stackSize = 0;
final Integer[] stack = new Integer[50];
final int len = data.length;
for (int j = 0; j < len;) {
final int value = data[j++] & 0xff;
if (debug && (value == 5 || value == 6 || value == 7 || value == 8
|| value == 12 || value == 25 || value == 26 || value == 27
|| value == 30 || value == 31)) {
System.out.println("Width calculation error command found " + value);
}
switch (value) {
case 1: // hstem
case 3: // vstem
return (stackSize % 2 != 0) ? stack[0] : null;
case 4: // vmoveto
return (stackSize > 1) ? stack[0] : null;
case 5: // rlineto
case 6: // hlineto
case 7: // vlineto
case 8: // rrcurveto
return null;
case 10: // callsubr
return (stackSize == 2) ? stack[0] : null;
case 11:
return null;
case 12:
final int vv = data[j++] & 0xff;
switch (vv) {
case 3: // and
case 4: // or
return stackSize == 3 ? stack[0] : null;
case 5: // not
return stackSize == 2 ? stack[0] : null;
case 9: // abs
return stackSize == 2 ? stack[0] : null;
case 10: // add
case 11: // sub
case 12: // div
return stackSize == 3 ? stack[0] : null;
case 14: // neg
return stackSize == 2 ? stack[0] : null;
case 15: // eq
return stackSize == 3 ? stack[0] : null;
case 18: // drop
return stackSize == 2 ? stack[0] : null;
case 22: // ifelse
return stackSize == 5 ? stack[0] : null;
case 23: // random
return stackSize == 2 ? stack[0] : null;
case 24: // mul
return stackSize == 3 ? stack[0] : null;
case 26: // sqrt
case 27: // dup
return stackSize == 2 ? stack[0] : null;
case 28: // exch
return stackSize == 3 ? stack[0] : null;
case 34: // hflex
return stackSize == 8 ? stack[0] : null;
case 35: // flex;
return stackSize == 14 ? stack[0] : null;
case 36: // hflex1
return stackSize == 10 ? stack[0] : null;
case 37: // flex1
return stackSize == 12 ? stack[0] : null;
}
return null;
case 14: // end char
return (stackSize > 0) ? stack[0] : null;
case 18: // hstemhm
case 19: // hintmask
case 20: // cntrmask
return (stackSize % 2 != 0) ? stack[0] : null;
case 21: // rmoveto
return (stackSize > 2) ? stack[0] : null;
case 22: // hmoveto
return (stackSize > 1) ? stack[0] : null;
case 23: // vstemhm
return (stackSize % 2 != 0) ? stack[0] : null;
case 24: // rcurveline
case 25: // rlinecurve
case 26: // vvcurveto
case 27: // hhcurveto
return null;
case 28: // shortint
stack[stackSize] = (((data[j] & 0xff) << 24) | ((data[j + 1] & 0xff) << 16)) >> 16;
j += 2;
stackSize++;
break;
case 29: //callgsubr
return (stackSize == 2) ? stack[0] : null;
case 30: // vhcurveto
case 31: // hvcurveto
return null;
default:
if (value >= 32 && value <= 246) {
stack[stackSize] = value - 139;
stackSize++;
} else if (value >= 247 && value <= 254) {
stack[stackSize] = (value < 251
? ((value - 247) << 8) + (data[j] & 0xff) + 108
: -((value - 251) << 8) - (data[j] & 0xff) - 108);
j++;
stackSize++;
} else if (value == 255) {
stack[stackSize] = (((data[j] & 0xff) << 24) | ((data[j + 1] & 0xff) << 16)
| ((data[j + 2] & 0xff) << 8) | (data[j + 3] & 0xff)) / 65536;
j += 4;
stackSize++;
} else {
return null;
}
}
}
return stack[0];
}
private static boolean parseCharString(final CIDState state, final byte[] data, final byte[][] localSubrToUse, final byte[][] globalSubrsIndexData) {
if (data == null || state.callDepths > 10) {
return false;
}
int stackSize = state.stackSize;
final double[] stack = state.stack;
final int len = data.length;
for (int j = 0; j < len;) {
final int value = data[j++] & 0xff;
CCSV validationCommand = null;
if (value == 12) {
final int q = data[j++] & 0xff;
if (q == 0) { // dotsection removal
data[j - 2] = (byte) 139;
data[j - 1] = 22;
stackSize = 0;
} else {
validationCommand = CS_VALIDATION2[q];
}
} else if (value == 28) { // number (16 bit)
stack[stackSize] = (((data[j] & 0xff) << 24) | ((data[j + 1] & 0xff) << 16)) >> 16;
j += 2;
stackSize++;
} else if (value == 14) {
if (stackSize >= 4) {
stackSize -= 4;
// if (this.seacAnalysisEnabled) {
// state.seac = stack.slice(stackSize, stackSize + 4);
// return false;
// }
}
validationCommand = CS_VALIDATION1[value];
} else if (value >= 32 && value <= 246) {
stack[stackSize] = value - 139;
stackSize++;
} else if (value >= 247 && value <= 254) {
stack[stackSize] = (value < 251
? ((value - 247) << 8) + (data[j] & 0xff) + 108
: -((value - 251) << 8) - (data[j] & 0xff) - 108);
j++;
stackSize++;
} else if (value == 255) {
stack[stackSize] = (((data[j] & 0xff) << 24) | ((data[j + 1] & 0xff) << 16)
| ((data[j + 2] & 0xff) << 8) | (data[j + 3] & 0xff)) / 65536;
j += 4;
stackSize++;
} else if (value == 19 || value == 20) {
state.hints += stackSize >> 1;
j += (state.hints + 7) >> 3;
stackSize %= 2;
validationCommand = CS_VALIDATION1[value];
} else if (value == 10 || value == 29) {
final byte[][] subrsIndex;
if (value == 10) {
subrsIndex = localSubrToUse;
} else {
subrsIndex = globalSubrsIndexData;
}
if (subrsIndex == null) {
return false;
}
int bias = 32768;
if (subrsIndex.length < 1240) {
bias = 107;
} else if (subrsIndex.length < 33900) {
bias = 1131;
}
final double subrNumber = stack[--stackSize] + bias;
if (subrNumber < 0 || subrNumber >= subrsIndex.length) {
return false;
}
state.stackSize = stackSize;
state.callDepths++;
final boolean valid = parseCharString(state, subrsIndex[(int) subrNumber], localSubrToUse, globalSubrsIndexData);
if (!valid) {
return false;
}
state.callDepths--;
stackSize = state.stackSize;
continue;
} else if (value == 11) {
state.stackSize = stackSize;
return true;
} else {
validationCommand = CS_VALIDATION1[value];
}
if (validationCommand != null) {
if (validationCommand.stem) {
state.hints += stackSize >> 1;
}
if (!state.undefStack && stackSize < validationCommand.min) {
// not enough parameters
return false;
}
if (state.firstStackClearing && validationCommand.stackClearing) {
state.firstStackClearing = false;
stackSize -= validationCommand.min;
if (stackSize >= 2 && validationCommand.stem) {
stackSize %= 2;
} else if (stackSize > 1) {
// too many stack size
}
if (stackSize > 0 && stack[stackSize - 1] >= 0) {
state.width = stack[stackSize - 1];
}
}
if (validationCommand.stackDelta != null) {
if (validationCommand.hasFunction) {
validationCommand.performFunction(validationCommand.id, stack, stackSize);
}
stackSize += validationCommand.stackDelta;
} else if (validationCommand.stackClearing) {
stackSize = 0;
} else if (validationCommand.resetStack) {
stackSize = 0;
state.undefStack = false;
} else if (validationCommand.undefStack) {
stackSize = 0;
state.undefStack = true;
state.firstStackClearing = false;
}
}
}
state.stackSize = stackSize;
return true;
}
private static CIDCharset parseCharset(final FileInput fb, final Number[] values,
final int charStringIndexLen, final String[] stringIndexData, final boolean isCID) throws IOException {
if (values == null || values.length == 0) {
return new CIDCharset(true, CHARSET_TYPE_ISO_ADOBE, CFF_ISO_ADOBE_STRINGS, null);
} else if (values[0].intValue() == CHARSET_TYPE_ISO_ADOBE) {
return new CIDCharset(true, CHARSET_TYPE_ISO_ADOBE, CFF_ISO_ADOBE_STRINGS, null);
} else if (values[0].intValue() == CHARSET_TYPE_EXPERT) {
return new CIDCharset(true, CHARSET_TYPE_EXPERT, CFF_EXPERT_STRINGS, null);
} else if (values[0].intValue() == CHARSET_TYPE_EXPERTSUBSET) {
return new CIDCharset(true, CHARSET_TYPE_EXPERTSUBSET, CFF_EXPERT_SUBSET_STRINGS, null);
} else {
final List charsetList = new ArrayList();
charsetList.add(".notdef");
final int start = values[0].intValue();
fb.moveTo(start);
final int format = fb.getU8();
int id, count;
final int length = charStringIndexLen - 1;
switch (format) {
case 0:
for (int i = 0; i < length; i++) {
id = (fb.getU8() << 8) | fb.getU8();
charsetList.add(isCID ? String.valueOf(id) : getFromStringIndexData(stringIndexData, id));
}
break;
case 1:
while (charsetList.size() <= length) {
id = (fb.getU8() << 8) | fb.getU8();
count = fb.getU8();
for (int i = 0; i <= count; i++) {
charsetList.add(isCID ? String.valueOf(id) : getFromStringIndexData(stringIndexData, id));
id++;
}
}
break;
case 2:
while (charsetList.size() <= length) {
id = (fb.getU8() << 8) | fb.getU8();
count = (fb.getU8() << 8) | fb.getU8();
for (int i = 0; i <= count; i++) {
charsetList.add(isCID ? String.valueOf(id) : getFromStringIndexData(stringIndexData, id));
id++;
}
}
break;
}
final int end = fb.getPosition();
final int rawLen = end - start;
final byte[] raw = new byte[rawLen];
fb.moveTo(start);
fb.read(raw);
String[] charsets = new String[charsetList.size()];
charsets = charsetList.toArray(charsets);
return new CIDCharset(false, format, charsets, raw);
}
}
private static CIDEncoding parseEncoding(final FileInput fb, final Number[] values, final String[] charset) throws IOException {
final int pos = values == null || values.length == 0 ? 0 : values[0].intValue();
final int[] encoding = new int[65536];
Arrays.fill(encoding, -1);
boolean predefined = false;
final int format;
byte[] raw = null;
if (pos == 0 || pos == 1) {
predefined = true;
format = pos;
final String[] baseEncoding = pos != 0 ? EXPERT_ENCODING : STANDARD_ENCODING;
for (int i = 0, ii = charset.length; i < ii; i++) {
int index = -1;
for (int j = 0; j < baseEncoding.length; j++) {
if (charset[i].equals(baseEncoding[j])) {
index = j;
}
}
if (index != -1) {
encoding[index] = i;
}
if (index != -1) {
encoding[index] = i;
}
}
} else {
fb.moveTo(pos);
format = fb.getU8();
switch (format & 0x7f) {
case 0:
final int glyphsCount = fb.getU8();
for (int i = 1; i <= glyphsCount; i++) {
encoding[fb.getU8()] = i;
}
break;
case 1:
final int rangesCount = fb.getU8();
int gid = 1;
for (int i = 0; i < rangesCount; i++) {
final int start = fb.getU8();
final int left = fb.getU8();
for (int j = start; j <= start + left; j++) {
encoding[j] = gid++;
}
}
break;
default:
throw new IOException("unsupported encoding found in CFF Data");
}
final int end = fb.getPosition();
final int rawLen = end - pos;
raw = new byte[rawLen];
fb.moveTo(pos);
fb.read(raw);
}
return new CIDEncoding(predefined, format, encoding, raw);
}
private static CIDFDSelect parseFDSelect(final FileInput fb, final Number[] values, final int len) throws IOException {
final int pos = values[0].intValue();
fb.moveTo(pos);
final int format = fb.getU8();
int[] fdSelect = null;
boolean invalidFirst = false;
switch (format) {
case 0:
fdSelect = new int[len];
for (int i = 0; i < len; i++) {
fdSelect[i] = fb.getU8();
}
break;
case 3:
final List temp = new ArrayList();
final int rangeCount = fb.getU16();
for (int i = 0; i < rangeCount; i++) {
int first = fb.getU16();
if (i == 0 && first != 0) {
invalidFirst = true;
first = 0;
}
final int fdIndex = fb.getU8();
final int next = fb.getU8() << 8 | fb.getU8();
fb.moveTo(fb.getPosition() - 2);
for (int j = first; j < next; j++) {
temp.add(fdIndex);
}
}
fdSelect = new int[temp.size()];
for (int i = 0; i < fdSelect.length; i++) {
fdSelect[i] = temp.get(i);
}
break;
}
final byte[] raw = new byte[len];
fb.moveTo(pos);
fb.read(raw);
if (invalidFirst) {
raw[3] = raw[4] = 0;
}
return new CIDFDSelect(fdSelect, raw);
}
private static String[] indexToStringArray(final FileInput fb, final int[] index) throws IOException {
if (index.length > 1) {
final String[] result = new String[index.length - 1];
for (int i = 0, ii = index.length - 1; i < ii; i++) {
final int len = index[i + 1] - index[i];
final byte[] data = new byte[len];
fb.moveTo(index[i]);
fb.read(data);
result[i] = (new String(data));
}
return result;
} else {
return null;
}
}
private static byte[][] indexToByteArray(final FileInput fb, final int[] index) throws IOException {
if (index.length > 1) {
final byte[][] result = new byte[index.length - 1][];
for (int i = 0, ii = index.length - 1; i < ii; i++) {
final int len = index[i + 1] - index[i];
if (len < 0) {
return result;
}
result[i] = new byte[len];
fb.moveTo(index[i]);
fb.read(result[i]);
}
return result;
} else {
return null;
}
}
private static void printDictEntry(final int key, final Number[] values) {
final StringBuilder vv = new StringBuilder();
for (final Number n : values) {
vv.append(n).append(' ');
}
System.out.println("DictEntry [ " + getKeyAsString(key) + " : " + vv.toString() + ']');
}
private static Dict[] parseDict(final FileInput fb, final int[] index) throws IOException {
Dict[] result = null;
if (index.length > 1) {
result = new Dict[index.length - 1];
for (int i = 0, ii = index.length - 1; i < ii; i++) {
final int len = index[i + 1] - index[i];
final byte[] data = new byte[len];
fb.moveTo(index[i]);
fb.read(data);
result[i] = new Dict(data);
}
} else {
System.err.println("No Dict Found");
}
return result;
}
public static String getKeyAsString(final int key) {
return key < 3000 ? getSingleByte(key) : getDoubleByte(key);
}
public static int getKeyType(final int key) {
switch (key) {
case VERSION:
case NOTICE:
case COPYRIGHT:
case FULLNAME:
case FAMILYNAME:
case WEIGHT:
case POSTSCRIPT:
case BASEFONTNAME:
case FONTNAME:
return TYPE_SID;
case FONTMATRIX:
case FONTBBOX:
case XUID:
return TYPE_ARRAY;
case BLUEVALUES:
case OTHERBLUES:
case FAMILYBLUES:
case FAMILYOTHERBLUES:
case STEMSNAPH:
case STEMSNAPV:
return TYPE_DELTA;
case PRIVATE:
return TYPE_PRIVATE;
case ROS:
return TYPE_ROS;
default:
return TYPE_NUMBER;
}
}
private static String getSingleByte(final int key) {
switch (key) {
case VERSION:
return "version";
case NOTICE:
return "Notice";
case FULLNAME:
return "FullName";
case FAMILYNAME:
return "FamilyName";
case WEIGHT:
return "Weight";
case FONTBBOX:
return "FontBBox";
case BLUEVALUES:
return "BlueValues";
case OTHERBLUES:
return "OtherBlues";
case FAMILYBLUES:
return "FamilyBlues";
case FAMILYOTHERBLUES:
return "FamilyOtherBlues";
case STDHW:
return "StdHW";
case STDVW:
return "StdVW";
case ESCAPE:
return "Escape";
case UNIQUEID:
return "UniqueID";
case XUID:
return "XUID";
case CHARSET:
return "Charset";
case ENCODING:
return "Encoding";
case CHARSTRINGS:
return "Charstrings";
case PRIVATE:
return "Private";
case SUBRS:
return "Subrs";
case DEFAULTWIDTHX:
return "DefaultWidthX";
case NOMINALWIDTHX:
return "NominalWidthx";
case RESERVED:
return "Reserved";
case SHORTINT:
return "ShortInt";
case LONGINT:
return "LongInt";
case BCD:
return "BCD";
default:
return "key not found" + key;
}
}
private static String getDoubleByte(final int key) {
switch (key) {
case COPYRIGHT:
return "CopyRight";
case ISFIXEDPITCH:
return "IsFixedPitch";
case ITALICANGLE:
return "ItalicAngle";
case UNDERLINEPOSITION:
return "UnderlinePosition";
case UNDERLINETHICKNESS:
return "UnderlineThickness";
case PAINTTYPE:
return "Painttype";
case CHARSTRINGTYPE:
return "CharstringType";
case FONTMATRIX:
return "FontFatrix";
case STROKEWIDTH:
return "StrokeWidth";
case BLUESCALE:
return "BlueScale";
case BLUESHIFT:
return "BlueShift";
case BLUEFUZZ:
return "BlueFuzz";
case STEMSNAPH:
return "StemSnapH";
case STEMSNAPV:
return "StemSnapV";
case FORCEBOLD:
return "ForceBold";
case LANGUAGEGROUP:
return "LanguageGroup";
case EXPANSIONFACTOR:
return "ExpansionFactor";
case INITIALRANDOMSEED:
return "InitialRandomSeed";
case SYNTHETICBASE:
return "SyntheticBase";
case POSTSCRIPT:
return "PostScript";
case BASEFONTNAME:
return "BaseFontName";
case BASEFONTBLEND:
return "BaseFontBlend";
case ROS:
return "Ros";
case CIDFONTVERSION:
return "CidFontVersion";
case CIDFONTREVISION:
return "CidFontRevision";
case CIDFONTTYPE:
return "CidFontType";
case CIDCOUNT:
return "CidCount";
case UIDBASE:
return "UidBase";
case FDARRAY:
return "FdArray";
case FDSELECT:
return "FdSelect";
case FONTNAME:
return "FontName";
default:
return "key not found " + key;
}
}
private static byte[] encodeInt(int value) {
final byte[] code;
if (value >= -107 && value <= 107) {
code = new byte[1];
code[0] = (byte) (value + 139);
} else if (value >= 108 && value <= 1131) {
code = new byte[2];
value -= 108;
code[0] = (byte) ((value >> 8) + 247);
code[1] = (byte) (value & 0xFF);
} else if (value >= -1131 && value <= -108) {
code = new byte[2];
value = -value - 108;
code[0] = (byte) ((value >> 8) + 251);
code[1] = (byte) (value & 0xFF);
} else if (value >= -32768 && value <= 32767) {
code = new byte[3];
code[0] = 0x1c;
code[1] = (byte) ((value >> 8) & 0xFF);
code[2] = code[1] = (byte) (value & 0xFF);
} else {
code = new byte[5];
code[0] = 0x1d;
code[1] = (byte) ((value >> 24) & 0xFF);
code[2] = (byte) ((value >> 16) & 0xFF);
code[3] = (byte) ((value >> 8) & 0xFF);
code[4] = (byte) (value & 0xFF);
}
return code;
}
private static byte[] encodeFloat(final float fv) {
final String str = Float.toString(fv);
final char[] values = str.toCharArray();
final StringBuilder nib = new StringBuilder();
for (int i = 0; i < values.length; ++i) {
final char a = values[i];
switch (a) {
case 'c':
nib.append(values[++i] == '-' ? 'c' : 'b');
break;
case '.':
nib.append('a');
break;
case '-':
nib.append('e');
break;
default:
nib.append(a);
break;
}
}
if ((nib.length() & 1) != 0) {
nib.append('f');
} else {
nib.append("ff");
}
final String nibStr = nib.toString();
final byte[] results = new byte[(nibStr.length() / 2) + 1];
results[0] = 30;
int p = 1;
for (int i = 0, ii = nibStr.length(); i < ii; i += 2) {
results[p++] = (byte) (Integer.parseInt(nibStr.substring(i, i + 2), 16));
}
return results;
}
public static void writeOTF(final FileOutput fo, final byte[] cffData, final CIDType1C font) {
// write sfnt version
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
final Dict topDict = font.topDicts[0];
final int firstCharIndex = 0;
final int lastCharIndex = 0;
// write CFF Table
// write os2 Table
}
public static void main(final String[] args) throws IOException {
final java.io.File file = new java.io.File("C:\\Users\\suda\\Desktop\\created\\results\\test11.cff");
final java.io.File file2 = new java.io.File("C:\\Users\\suda\\Desktop\\created\\results\\suda.cff");
final CIDType1C font = parse(new FileInput(file));
final byte[] bb = fix(font, "mingle");
final FileOutput fo = new FileOutput(file2);
fo.write(bb);
fo.close();
parse(new FileInput(file2));
}
// private static class TopDict {
//
// Number copyRight = null;
// Number fullName = null;
// Number familyName = null;
// Number weight = null;
//
// Number isFixedPitch = null;
// Number italicAngle = 0;
// Number underLinePostion = -100;
// Number underLineThickness = 50;
// Number paintType = null;
// Number charstringType = 2;
// float[] fontMatrix = {0.001f, 0, 0, 0.001f, 0, 0};
// float[] fontBBox = {0, 0, 0, 0};
// Number strokeWidth = 0;
// Number charset = 0;
// Number Encoding = 0;
// Number CharStrings = 0;
// float[] privateValues = null;
// Number postscript = null;
// Number baseFontName = null;
// float[] baseFontBlend = null;
// }
}