lcdf-typetools-2.108/0000755000175000017500000000000013423377073011506 500000000000000lcdf-typetools-2.108/libefont/0000755000175000017500000000000013423377072013307 500000000000000lcdf-typetools-2.108/libefont/pairop.cc0000644000175000017500000000641313423375327015035 00000000000000// -*- related-file-name: "../include/efont/pairop.hh" -*- /* pairop.{cc,hh} -- ligature/kern font metrics * * Copyright (c) 1998-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include namespace Efont { PairProgram::PairProgram(const PairProgram &o) : _reversed(o._reversed), _left_map(o._left_map), _op(o._op) { } void PairProgram::reserve_glyphs(int e) { if (e <= _left_map.size()) return; _left_map.resize(e, -1); } PairOpIndex PairProgram::find(GlyphIndex leftgi, GlyphIndex rightgi) const { PairOpIndex opi = find_left(leftgi); while (opi >= 0) { if (op(opi).right() == rightgi) return opi; opi = op(opi).next_left(); } return -1; } bool PairProgram::add_kern(GlyphIndex left, GlyphIndex right, int ki) { PairOp newop(left, right, ki, _left_map[left]); int newopi = _op.size(); _op.push_back(newop); _left_map[left] = newopi; //PairOpIndex duplicate = map[newop]; //map.add(newop, newopi); return false; } bool PairProgram::add_lig(GlyphIndex left, GlyphIndex right, GlyphIndex result, int kind) { PairOp newop(left, right, result, kind, _left_map[left]); int newopi = _op.size(); _op.push_back(newop); _left_map[left] = newopi; //PairOpIndex duplicate = map[newop]; //map.add(newop, newopi); return false; } void PairProgram::unreverse() { if (!_reversed) return; _left_map.assign(_left_map.size(), -1); for (PairOpIndex opi = _op.size() - 1; opi >= 0; opi--) { PairOp &o = _op[opi]; PairOpIndex l = o.left(); o.set_next(_left_map[l]); _left_map[l] = opi; } _reversed = false; } void PairProgram::optimize() { /* PairOpIndex opi; // Get rid of 0-valued kerns. for (opi = 0; opi < opcount(); opi++) { PairOp &o = op(opi); if (o.is_kern() && o.value() == 0) o.noopify(); }*/ } inline const char * PairProgram::print_name(GlyphIndex) const { #if 0 if (gi == opAnychar) return "*"; else return glyph(gi).name(); #endif return 0; } void PairProgram::print() const { #if 0 for (GlyphIndex gi = 0; gi < glyphblock.size(); gi++) if (glyphblock[gi] != -1) printf("%s->B%d ", glyph(gi).name().c_str(), glyphblock[gi]); printf("\n"); for (int i = 0; i < blocks.size(); i++) { printf("B%-2d: ", i); PairOpBlock &opb = *blocks[i]; for (int j = 0; j < opb.size(); j++) if (opb[j].is_lig()) printf("%s->%s ", printname(opb[j].right()), printname(opb[j].result())); else if (opb[j].is_kern()) printf("%s[%g] ", printname(opb[j].right()), kern(opb[j].value())); else if (opb[j].is_noop()) printf(". "); if (blocks[i]->nextblock != -1) printf(" :B%d", blocks[i]->nextblock); printf("\n"); } #endif } } lcdf-typetools-2.108/libefont/otfpost.cc0000644000175000017500000002162213423375327015240 00000000000000// -*- related-file-name: "../include/efont/otfpost.hh" -*- /* otfpost.{cc,hh} -- OpenType post table * * Copyright (c) 2006-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include // for ntohl() #define USHORT_AT(d) (Data::u16_aligned(d)) #define SHORT_AT(d) (Data::s16_aligned(d)) #define ULONG_AT(d) (Data::u32_aligned(d)) #define LONG_AT(d) (Data::s32_aligned(d)) namespace Efont { namespace OpenType { static const char * const mac_names[] = { ".notdef", ".null", "nonmarkingreturn", "space", // 0-3 "exclam", "quotedbl", "numbersign", "dollar", // 4-7 "percent", "ampersand", "quotesingle", "parenleft", // 8-11 "parenright", "asterisk", "plus", "comma", // 12-15 "hyphen", "period", "slash", "zero", // 16-19 "one", "two", "three", "four", // 20-23 "five", "six", "seven", "eight", // 24-27 "nine", "colon", "semicolon", "less", // 28-31 "equal", "greater", "question", "at", // 32-35 "A", "B", "C", "D", // 36-39 "E", "F", "G", "H", // 40-43 "I", "J", "K", "L", // 44-47 "M", "N", "O", "P", // 48-51 "Q", "R", "S", "T", // 52-55 "U", "V", "W", "X", // 56-59 "Y", "Z", "bracketleft", "backslash", // 60-63 "bracketright", "asciicircum", "underscore", "grave", // 64-67 "a", "b", "c", "d", // 68-71 "e", "f", "g", "h", // 72-75 "i", "j", "k", "l", // 76-79 "m", "n", "o", "p", // 80-83 "q", "r", "s", "t", // 84-87 "u", "v", "w", "x", // 88-91 "y", "z", "braceleft", "bar", // 92-95 "braceright", "asciitilde", "Adieresis", "Aring", // 96-99 "Ccedilla", "Eacute", "Ntilde", "Odieresis", // 100-103 "Udieresis", "aacute", "agrave", "acircumflex", // 104-107 "adieresis", "atilde", "aring", "ccedilla", // 108-111 "eacute", "egrave", "ecircumflex", "edieresis", // 112-115 "iacute", "igrave", "icircumflex", "idieresis", // 116-119 "ntilde", "oacute", "ograve", "ocircumflex", // 120-123 "odieresis", "otilde", "uacute", "ugrave", // 124-127 "ucircumflex", "udieresis", "dagger", "degree", // 128-131 "cent", "sterling", "section", "bullet", // 132-135 "paragraph", "germandbls", "registered", "copyright", // 136-139 "trademark", "acute", "dieresis", "notequal", // 140-143 "AE", "Oslash", "infinity", "plusminus", // 144-147 "lessequal", "greaterequal", "yen", "mu", // 148-151 "partialdiff", "summation", "product", "pi", // 152-155 "integral", "ordfeminine", "ordmasculine", "Omega", // 156-159 "ae", "oslash", "questiondown", "exclamdown", // 160-163 "logicalnot", "radical", "florin", "approxequal", // 164-167 "Delta", "guillemotleft", "guillemotright", "ellipsis", // 168-171 "nonbreakingspace", "Agrave", "Atilde", "Otilde", // 172-175 "OE", "oe", "endash", "emdash", // 176-179 "quotedblleft", "quotedblright", "quoteleft", "quoteright", // 180-183 "divide", "lozenge", "ydieresis", "Ydieresis", // 184-187 "fraction", "currency", "guilsinglleft", "guilsinglright", // 188-191 "fi", "fl", "daggerdbl", "periodcentered", // 192-195 "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex", // 196-199 "Ecircumflex", "Aacute", "Edieresis", "Egrave", // 200-203 "Iacute", "Icircumflex", "Idieresis", "Igrave", // 204-207 "Oacute", "Ocircumflex", "apple", "Ograve", // 208-211 "Uacute", "Ucircumflex", "Ugrave", "dotlessi", // 212-215 "circumflex", "tilde", "macron", "breve", // 216-219 "dotaccent", "ring", "cedilla", "hungarumlaut", // 220-223 "ogonek", "caron", "Lslash", "lslash", // 224-227 "Scaron", "scaron", "Zcaron", "zcaron", // 228-231 "brokenbar", "Eth", "eth", "Yacute", // 232-235 "yacute", "Thorn", "thorn", "minus", // 236-239 "multiply", "onesuperior", "twosuperior", "threesuperior", // 240-243 "onehalf", "onequarter", "threequarters", "franc", // 244-247 "Gbreve", "gbreve", "Idotaccent", "Scedilla", // 248-251 "scedilla", "Cacute", "cacute", "Ccaron", // 252-255 "ccaron", "dcroat" // 256-257 }; Post::Post(const String &s, ErrorHandler *errh) : _str(s), _version(0) { _str.align_long(); _error = parse_header(errh ? errh : ErrorHandler::silent_handler()); } int Post::parse_header(ErrorHandler *errh) { // HEADER FORMAT: // 0 FIXED version // 4 FIXED italicAngle // 8 FWORD underlinePosition // 10 FWORD underlineThickness // 12 ULONG isFixedPitch // 16 ULONG minMemType42 // 20 ULONG maxMemType42 // 24 ULONG minMemType1 // 28 ULONG maxMemType1 int len = _str.length(); const uint8_t *data = _str.udata(); if (HEADER_SIZE > len) return errh->error("OTF post table too small"), -EFAULT; _version = USHORT_AT(data); // ignore minor version number // except that version 2.5 isn't compatible if (_version < 1 || _version > 3 || (_version == 2 && USHORT_AT(data + 2) == 0x5000)) return errh->error("bad post version number"), -ERANGE; if (_version == 2) { // VERSION 2.0 GLYPH NAMES FORMAT: // 32 USHORT numberOfGlyphs // 34 USHORT glyphNameIndex[mumberOfGlyphs] // CHAR names[...] if (HEADER_SIZE + 2 > len || ((_nglyphs = USHORT_AT(data + HEADER_SIZE)), HEADER_SIZE + 2 + 2 * _nglyphs > len)) return errh->error("OTF post table too small for glyph map"), -EFAULT; int pos = HEADER_SIZE + 2 + 2 * _nglyphs; while (pos < len && pos + data[pos] < len) { _extend_glyph_names.push_back(pos); pos += 1 + data[pos]; } const uint8_t *gni = data + HEADER_SIZE + 2; for (int i = 0, g; i < _nglyphs; ++i, gni += 2) if ((g = USHORT_AT(gni)) >= _extend_glyph_names.size() + N_MAC_GLYPHS) return errh->error("bad glyph name index in post"); } else if (_version == 1) _nglyphs = N_MAC_GLYPHS; else _nglyphs = -1; return 0; } double Post::italic_angle() const { if (error() < 0) return -1; return (double) LONG_AT(_str.udata() + 4) / 65536.; } bool Post::is_fixed_pitch() const { if (error() < 0) return false; return ULONG_AT(_str.udata() + 12) != 0; } bool Post::glyph_names(Vector &gnames) const { gnames.clear(); if (error() < 0) return false; if (_version == 1) { for (int i = 0; i < N_MAC_GLYPHS; i++) gnames.push_back(mac_names[i]); return true; } else if (_version == 2) { const uint8_t *data = _str.udata(); const uint8_t *gni = data + HEADER_SIZE + 2; for (int i = 0; i < _nglyphs; i++, gni += 2) { int g = USHORT_AT(gni); if (g < N_MAC_GLYPHS) gnames.push_back(mac_names[g]); else { const uint8_t *n = data + _extend_glyph_names[g - N_MAC_GLYPHS]; gnames.push_back(PermString((const char *) n + 1, *n)); } } return true; } else return false; } }} lcdf-typetools-2.108/libefont/t1fontskel.cc0000644000175000017500000003554413423375327015644 00000000000000/* t1fontskel.cc -- Type 1 font skeleton * * Copyright (c) 1998-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include namespace Efont { #if HAVE_ADOBE_CODE static const char* othersubrs_code = // This version of the OtherSubrs code for old PostScript interpreters comes from // https://github.com/adobe-type-tools/afdko/blob/master/FDK/Tools/Programs/public/lib/source/t1write/t1write_flexothers.txt // (commit 3f4eeec). The Adobe Font Development Kit is licensed by the Apache // License, 2.0, which permits this embedding. "% Copyright 1987-1990 Adobe Systems Incorporated. All rights reserved.\n" "/OtherSubrs[systemdict/internaldict known{1183615869 systemdict/internaldict\n" "get exec/FlxProc known{save true}{false}ifelse}{userdict/internaldict known\n" "not{userdict/internaldict{count 0 eq{/internaldict errordict/invalidaccess get\n" "exec}if dup type/integertype ne{/internaldict errordict/invalidaccess get exec\n" "}if dup 1183615869 eq{pop 0}{/internaldict errordict/invalidaccess get exec}\n" "ifelse}dup 14 get 1 25 dict put bind executeonly put}if 1183615869 userdict\n" "/internaldict get exec/FlxProc known{save true}{false}ifelse}ifelse[systemdict\n" "/internaldict known not{100 dict/begin cvx/mtx matrix/def cvx}if systemdict\n" "/currentpacking known{currentpacking true setpacking}if{systemdict\n" "/internaldict known{1183615869 systemdict/internaldict get exec dup/$FlxDict\n" "known not{dup dup length exch maxlength eq{pop userdict dup/$FlxDict known not\n" "{100 dict begin/mtx matrix def dup/$FlxDict currentdict put end}if}{100 dict\n" "begin/mtx matrix def dup/$FlxDict currentdict put end}ifelse}if/$FlxDict get\n" "begin}if grestore/exdef{exch def}def/dmin exch abs 100 div def/epX exdef/epY\n" "exdef/c4y2 exdef/c4x2 exdef/c4y1 exdef/c4x1 exdef/c4y0 exdef/c4x0 exdef/c3y2\n" "exdef/c3x2 exdef/c3y1 exdef/c3x1 exdef/c3y0 exdef/c3x0 exdef/c1y2 exdef/c1x2\n" "exdef/c2x2 c4x2 def/c2y2 c4y2 def/yflag c1y2 c3y2 sub abs c1x2 c3x2 sub abs gt\n" "def/PickCoords{{c1x0 c1y0 c1x1 c1y1 c1x2 c1y2 c2x0 c2y0 c2x1 c2y1 c2x2 c2y2}{\n" "c3x0 c3y0 c3x1 c3y1 c3x2 c3y2 c4x0 c4y0 c4x1 c4y1 c4x2 c4y2}ifelse/y5 exdef/x5\n" "exdef/y4 exdef/x4 exdef/y3 exdef/x3 exdef/y2 exdef/x2 exdef/y1 exdef/x1 exdef\n" "/y0 exdef/x0 exdef}def mtx currentmatrix pop mtx 0 get abs 1e-05 lt mtx 3 get\n" "abs 1e-05 lt or{/flipXY -1 def}{mtx 1 get abs 1e-05 lt mtx 2 get abs 1e-05 lt\n" "or{/flipXY 1 def}{/flipXY 0 def}ifelse}ifelse/erosion 1 def systemdict\n" "/internaldict known{1183615869 systemdict/internaldict get exec dup/erosion\n" "known{/erosion get/erosion exch def}{pop}ifelse}if yflag{flipXY 0 eq c3y2 c4y2\n" "eq or{false PickCoords}{/shrink c3y2 c4y2 eq{0}{c1y2 c4y2 sub c3y2 c4y2 sub\n" "div abs}ifelse def/yshrink{c4y2 sub shrink mul c4y2 add}def/c1y0 c3y0 yshrink\n" "def/c1y1 c3y1 yshrink def/c2y0 c4y0 yshrink def/c2y1 c4y1 yshrink def/c1x0\n" "c3x0 def/c1x1 c3x1 def/c2x0 c4x0 def/c2x1 c4x1 def/dY 0 c3y2 c1y2 sub round\n" "dtransform flipXY 1 eq{exch}if pop abs def dY dmin lt PickCoords y2 c1y2 sub\n" "abs .001 gt{c1x2 c1y2 transform flipXY 1 eq{exch}if/cx exch def/cy exch def/dY\n" "0 y2 c1y2 sub round dtransform flipXY 1 eq{exch}if pop def dY round dup 0 ne{\n" "/dY exdef}{pop dY 0 lt{-1}{1}ifelse/dY exdef}ifelse/erode PaintType 2 ne\n" "erosion .5 ge and def erode{/cy cy .5 sub def}if/ey cy dY add def/ey ey\n" "ceiling ey sub ey floor add def erode{/ey ey .5 add def}if ey cx flipXY 1 eq{\n" "exch}if itransform exch pop y2 sub/eShift exch def/y1 y1 eShift add def/y2 y2\n" "eShift add def/y3 y3 eShift add def}if}ifelse}{flipXY 0 eq c3x2 c4x2 eq or{\n" "false PickCoords}{/shrink c3x2 c4x2 eq{0}{c1x2 c4x2 sub c3x2 c4x2 sub div abs}\n" "ifelse def/xshrink{c4x2 sub shrink mul c4x2 add}def/c1x0 c3x0 xshrink def/c1x1\n" "c3x1 xshrink def/c2x0 c4x0 xshrink def/c2x1 c4x1 xshrink def/c1y0 c3y0 def\n" "/c1y1 c3y1 def/c2y0 c4y0 def/c2y1 c4y1 def/dX c3x2 c1x2 sub round 0 dtransform\n" "flipXY -1 eq{exch}if pop abs def dX dmin lt PickCoords x2 c1x2 sub abs .001 gt\n" "{c1x2 c1y2 transform flipXY -1 eq{exch}if/cy exch def/cx exch def/dX x2 c1x2\n" "sub round 0 dtransform flipXY -1 eq{exch}if pop def dX round dup 0 ne{/dX\n" "exdef}{pop dX 0 lt{-1}{1}ifelse/dX exdef}ifelse/erode PaintType 2 ne erosion\n" ".5 ge and def erode{/cx cx .5 sub def}if/ex cx dX add def/ex ex ceiling ex sub\n" "ex floor add def erode{/ex ex .5 add def}if ex cy flipXY -1 eq{exch}if\n" "itransform pop x2 sub/eShift exch def/x1 x1 eShift add def/x2 x2 eShift add\n" "def/x3 x3 eShift add def}if}ifelse}ifelse x2 x5 eq y2 y5 eq or{x5 y5 lineto}{\n" "x0 y0 x1 y1 x2 y2 curveto x3 y3 x4 y4 x5 y5 curveto}ifelse epY epX}systemdict\n" "/currentpacking known{exch setpacking}if/exec cvx/end cvx]cvx executeonly exch\n" "{pop true exch restore}{systemdict/internaldict known not{1183615869 userdict\n" "/internaldict get exec exch/FlxProc exch put true}{1183615869 systemdict\n" "/internaldict get exec dup length exch maxlength eq{false}{1183615869\n" "systemdict/internaldict get exec exch/FlxProc exch put true}ifelse}ifelse}\n" "ifelse{systemdict/internaldict known{{1183615869 systemdict/internaldict get\n" "exec/FlxProc get exec}}{{1183615869 userdict/internaldict get exec/FlxProc get\n" "exec}}ifelse executeonly}if{gsave currentpoint newpath moveto}executeonly{\n" "currentpoint grestore gsave currentpoint newpath moveto}executeonly{systemdict\n" "/internaldict known not{pop 3}{1183615869 systemdict/internaldict get exec dup\n" "/startlock known{/startlock get exec}{dup/strtlck known{/strtlck get exec}{pop\n" "3}ifelse}ifelse}ifelse}executeonly]def"; #else static const char* othersubrs_code = "/OtherSubrs\n" "[\n" "{pop pop pop grestore 12 6 roll curveto curveto pop pop} executeonly\n" "{gsave currentpoint newpath moveto} executeonly\n" "{currentpoint currentpoint newpath moveto} executeonly\n" "{} executeonly\n" "] noaccess def"; #endif Type1Font * Type1Font::skeleton_make(PermString font_name, const String &version) { Type1Font *output = new Type1Font(font_name); // %!PS-Adobe-Font comment StringAccum sa; sa << "%!PS-AdobeFont-1.0: " << font_name; if (version) sa << ' ' << version; output->add_item(new Type1CopyItem(sa.take_string())); output->_dict_deltas[dF] = 3; // Private, FontInfo, Encoding output->_dict_deltas[dP] = 3; // OtherSubrs, Subrs, CharStrings return output; } void Type1Font::skeleton_comments_end() { // count members of font dictionary add_definition(dF, new Type1Definition("FontName", "/" + String(_font_name), "def")); } void Type1Font::skeleton_fontinfo_end() { if (first_dict_item(Type1Font::dFI) >= 0) add_item(new Type1CopyItem("end readonly def")); else add_item(new Type1CopyItem("% no FontInfo dict")); } void Type1Font::skeleton_fontdict_end() { // switch to eexec add_item(new Type1CopyItem("currentdict end")); add_item(new Type1EexecItem(true)); // Private dictionary add_definition(Type1Font::dP, Type1Definition::make_literal("-|", "{string currentfile exch readstring pop}", "executeonly def")); set_charstring_definer(" -| "); add_definition(Type1Font::dP, Type1Definition::make_literal("|-", "{noaccess def}", "executeonly def")); add_definition(Type1Font::dP, Type1Definition::make_literal("|", "{noaccess put}", "executeonly def")); } void Type1Font::skeleton_private_end() { add_item(new Type1CopyItem(othersubrs_code)); // Subrs add_item(new Type1SubrGroupItem(this, true, "/Subrs 0 array")); add_item(new Type1CopyItem("|-")); // CharStrings add_item(new Type1SubrGroupItem(this, false, "2 index /CharStrings 0 dict dup begin")); // completion add_item(new Type1CopyItem("end\n\ end\n\ readonly put\n\ noaccess put\n\ dup /FontName get exch definefont pop\n\ mark currentfile closefile")); add_item(new Type1EexecItem(false)); add_item(new Type1CopyItem("\ 0000000000000000000000000000000000000000000000000000000000000000\n\ 0000000000000000000000000000000000000000000000000000000000000000\n\ 0000000000000000000000000000000000000000000000000000000000000000\n\ 0000000000000000000000000000000000000000000000000000000000000000\n\ 0000000000000000000000000000000000000000000000000000000000000000\n\ 0000000000000000000000000000000000000000000000000000000000000000\n\ 0000000000000000000000000000000000000000000000000000000000000000\n\ 0000000000000000000000000000000000000000000000000000000000000000\n\ cleartomark")); } void Type1Font::skeleton_common_subrs() { // - first four Subrs have fixed definitions // - 0: "3 0 callothersubr pop pop setcurrentpoint return" set_subr(0, Type1Charstring(String::make_stable("\216\213\014\020\014\021\014\021\014\041\013", 11)), " |"); // - 1: "0 1 callothersubr return" set_subr(1, Type1Charstring(String::make_stable("\213\214\014\020\013", 5)), " |"); // - 2: "0 2 callothersubr return" set_subr(2, Type1Charstring(String::make_stable("\213\215\014\020\013", 5)), " |"); // - 3: "return" set_subr(3, Type1Charstring(String::make_stable("\013", 1)), " |"); // - 4: "1 3 callothersubr pop callsubr return" set_subr(4, Type1Charstring(String::make_stable("\214\216\014\020\014\021\012\013", 8)), " |"); } static void add_number_def(Type1Font *output, int dict, PermString name, const Type1Font *font) { double v; if (Type1Definition *t1d = font->dict(dict, name)) if (t1d->value_num(v)) output->add_definition(dict, Type1Definition::make(name, v, "def")); } static void add_copy_def(Type1Font *output, int dict, PermString name, const Type1Font *font, const char *definer = "def") { if (Type1Definition *t1d = font->dict(dict, name)) output->add_definition(dict, Type1Definition::make_literal(name, t1d->value(), definer)); } static String font_dict_string(const Type1Font *font, int dict, PermString name) { String s; if (Type1Definition *d = font->dict(dict, name)) if (d->value_string(s)) return s; return String(); } Type1Font * Type1Font::skeleton_make_copy(const Type1Font *font, PermString font_name, const Vector *xuid_extension) { String version = font_dict_string(font, dFI, "version"); Type1Font *output = skeleton_make(font_name, version); // other comments from font header for (int i = 0; i < font->nitems(); i++) if (Type1CopyItem *c = font->item(i)->cast_copy()) { if (c->length() > 1 && c->value()[0] == '%') { if (c->value()[1] != '!') output->add_item(new Type1CopyItem(c->value())); } else break; } else break; output->skeleton_comments_end(); // FontInfo dictionary if (version) output->add_definition(dFI, Type1Definition::make_string("version", version, "readonly def")); if (String s = font_dict_string(font, dFI, "Notice")) output->add_definition(dFI, Type1Definition::make_string("Notice", s, "readonly def")); if (String s = font_dict_string(font, dFI, "Copyright")) output->add_definition(dFI, Type1Definition::make_string("Copyright", s, "readonly def")); if (String s = font_dict_string(font, dFI, "FullName")) output->add_definition(dFI, Type1Definition::make_string("FullName", s, "readonly def")); if (String s = font_dict_string(font, dFI, "FamilyName")) output->add_definition(dFI, Type1Definition::make_string("FamilyName", s, "readonly def")); if (String s = font_dict_string(font, dFI, "Weight")) output->add_definition(dFI, Type1Definition::make_string("Weight", s, "readonly def")); if (Type1Definition *t1d = font->fi_dict("isFixedPitch")) { bool v; if (t1d->value_bool(v)) output->add_definition(dFI, Type1Definition::make_literal("isFixedPitch", (v ? "true" : "false"), "def")); } add_number_def(output, dFI, "ItalicAngle", font); add_number_def(output, dFI, "UnderlinePosition", font); add_number_def(output, dFI, "UnderlineThickness", font); output->skeleton_fontinfo_end(); // Encoding, other font dictionary entries output->add_type1_encoding(new Type1Encoding(*font->type1_encoding())); add_number_def(output, dF, "PaintType", font); add_number_def(output, dF, "FontType", font); add_copy_def(output, dF, "FontMatrix", font, "readonly def"); add_number_def(output, dF, "StrokeWidth", font); if (!xuid_extension) add_number_def(output, dF, "UniqueID", font); add_copy_def(output, dF, "XUID", font, "readonly def"); if (xuid_extension) { Vector xuid; if (Type1Definition *xuid_def = output->dict("XUID")) xuid_def->value_numvec(xuid); if (!xuid.size()) { Type1Definition *uid_def = font->dict("UniqueID"); int uid; if (uid_def && uid_def->value_int(uid)) { xuid.push_back(1); xuid.push_back(uid); } } if (xuid.size()) { for (int i = 0; i < xuid_extension->size(); i++) xuid.push_back((*xuid_extension)[i]); Type1Definition *xuid_def = output->ensure(dF, "XUID"); xuid_def->set_numvec(xuid); } } add_copy_def(output, dF, "FontBBox", font, "readonly def"); output->skeleton_fontdict_end(); // Private dictionary add_copy_def(output, dP, "BlueValues", font); add_copy_def(output, dP, "OtherBlues", font); add_copy_def(output, dP, "FamilyBlues", font); add_copy_def(output, dP, "FamilyOtherBlues", font); add_number_def(output, dP, "BlueScale", font); add_number_def(output, dP, "BlueShift", font); add_number_def(output, dP, "BlueFuzz", font); add_copy_def(output, dP, "StdHW", font); add_copy_def(output, dP, "StdVW", font); add_copy_def(output, dP, "StemSnapH", font); add_copy_def(output, dP, "StemSnapV", font); add_copy_def(output, dP, "ForceBold", font); add_number_def(output, dP, "LanguageGroup", font); add_number_def(output, dP, "ExpansionFactor", font); if (!xuid_extension) add_number_def(output, dP, "UniqueID", font); output->add_definition(dP, Type1Definition::make_literal("MinFeature", "{16 16}", "|-")); output->add_definition(dP, Type1Definition::make_literal("password", "5839", "def")); output->add_definition(dP, Type1Definition::make_literal("lenIV", "0", "def")); output->skeleton_private_end(); return output; } } lcdf-typetools-2.108/libefont/cff.cc0000644000175000017500000015473113423375327014310 00000000000000// -*- related-file-name: "../include/efont/cff.hh" -*- /* cff.{cc,hh} -- Compact Font Format fonts * * Copyright (c) 1998-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #ifndef static_assert #define static_assert(c, msg) switch ((int) (c)) case 0: case (c): #endif namespace Efont { const char * const Cff::operator_names[] = { "version", "Notice", "FullName", "FamilyName", "Weight", "FontBBox", "BlueValues", "OtherBlues", "FamilyBlues", "FamilyOtherBlues", "StdHW", "StdVW", "UNKNOWN_12", "UniqueID", "XUID", "charset", "Encoding", "CharStrings", "Private", "Subrs", "defaultWidthX", "nominalWidthX", "UNKNOWN_22", "UNKNOWN_23", "UNKNOWN_24", "UNKNOWN_25", "UNKNOWN_26", "UNKNOWN_27", "UNKNOWN_28", "UNKNOWN_29", "UNKNOWN_30", "UNKNOWN_31", "Copyright", "isFixedPitch", "ItalicAngle", "UnderlinePosition", "UnderlineThickness", "PaintType", "CharstringType", "FontMatrix", "StrokeWidth", "BlueScale", "BlueShift", "BlueFuzz", "StemSnapH", "StemSnapV", "ForceBold", "UNKNOWN_12_15", "UNKNOWN_12_16", "LanguageGroup", "ExpansionFactor", "initialRandomSeed", "SyntheticBase", "PostScript", "BaseFontName", "BaseFontBlend", "UNKNOWN_12_24", "UNKNOWN_12_25", "UNKNOWN_12_26", "UNKNOWN_12_27", "UNKNOWN_12_28", "UNKNOWN_12_29", "ROS", "CIDFontVersion", "CIDFontRevision", "CIDFontType", "CIDCount", "UIDBase", "FDArray", "FDSelect", "FontName" }; const int Cff::operator_types[] = { tSID, tSID, tSID, tSID, // version, Notice, FullName, FamilyName tSID, tArray4, tP+tArray, tP+tArray, // Weight, FontBBox, BlueValues, OtherBlues tP+tArray, tP+tArray, tP+tNumber, tP+tNumber, // FamBlues, FamOthBlues, StdHW, StdVW tNone, tNumber, tArray, tOffset, // escape, UniqueID, XUID, charset tOffset, tOffset, tPrivateType, tP+tLocalOffset, // Encoding, CharStrings, Private, Subrs tP+tNumber, tP+tNumber, tNone, tNone, // defaultWX, nominalWX, 22, 23 tNone, tNone, tNone, tNone, // 24, 25, 26, 27 tNone, tNone, tNone, tNone, // 28, 29, 30, 31 tSID, tBoolean, tNumber, tNumber, // Copyright, isFixedPitch, ItalicAngle, UnderlinePosition tNumber, tNumber, tNumber, tArray6, // UnderlineThickness, PaintType, CharstringType, FontMatrix tNumber, tP+tNumber, tP+tNumber, tP+tNumber, // StrokeWidth, BlueScale, BlueShift, BlueFuzz tP+tArray, tP+tArray, tP+tBoolean, tNone, // StemSnapH, StemSnapV, ForceBold, 12 15 tNone, tP+tNumber, tP+tNumber, tP+tNumber, // 12 16, LanguageGroup, ExpansionFactor, initialRandomSeed tNumber, tSID, tSID, tArray, // SyntheticBase, PostScript, BaseFontName, BaseFontBlend tNone, tNone, tNone, tNone, // 12 24, 12 25, 12 26, 12 27 tNone, tNone, tArray, tNumber, // 12 28, 12 29, ROS, CIDFontVersion tNumber, tNumber, tNumber, tNumber, // CIDFontRevision, CIDFontType, CIDCount, UIDBase tOffset, tOffset, tSID // FDArray, FDSelect, FontName }; static PermString::Initializer initializer; static const char * const standard_strings[] = { // Automatically generated from Appendix A of the CFF specification; do // not edit. Size should be 391. ".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" }; static PermString standard_permstrings[Cff::NSTANDARD_STRINGS]; static HashMap standard_permstrings_map(-1); static const int standard_encoding[] = { // Automatically generated from Appendix B of the CFF specification; do // not edit. Size should be 256. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 0, 111, 112, 113, 114, 0, 115, 116, 117, 118, 119, 120, 121, 122, 0, 123, 0, 124, 125, 126, 127, 128, 129, 130, 131, 0, 132, 133, 0, 134, 135, 136, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 139, 0, 0, 0, 0, 140, 141, 142, 143, 0, 0, 0, 0, 0, 144, 0, 0, 0, 145, 0, 0, 146, 147, 148, 149, 0, 0, 0, 0 }; static const int expert_encoding[] = { // Automatically generated from Appendix B of the CFF specification; do // not edit. Size should be 256. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 229, 230, 0, 231, 232, 233, 234, 235, 236, 237, 238, 13, 14, 15, 99, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 27, 28, 249, 250, 251, 252, 0, 253, 254, 255, 256, 257, 0, 0, 0, 258, 0, 0, 259, 260, 261, 262, 0, 0, 263, 264, 265, 0, 266, 109, 110, 267, 268, 269, 0, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 304, 305, 306, 0, 0, 307, 308, 309, 310, 311, 0, 312, 0, 0, 313, 0, 0, 314, 315, 0, 0, 316, 317, 318, 0, 0, 0, 158, 155, 163, 319, 320, 321, 322, 323, 324, 325, 0, 0, 326, 150, 164, 169, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378 }; static const int iso_adobe_charset[] = { // Automatically generated from Appendix C of the CFF specification; do // not edit. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228 }; static const int expert_charset[] = { // Automatically generated from Appendix C of the CFF specification; do // not edit. 0, 1, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 13, 14, 15, 99, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 27, 28, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 109, 110, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 158, 155, 163, 319, 320, 321, 322, 323, 324, 325, 326, 150, 164, 169, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378 }; static const int expert_subset_charset[] = { // Automatically generated from Appendix C of the CFF specification; do // not edit. 0, 1, 231, 232, 235, 236, 237, 238, 13, 14, 15, 99, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 27, 28, 249, 250, 251, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 109, 110, 267, 268, 269, 270, 272, 300, 301, 302, 305, 314, 315, 158, 155, 163, 320, 321, 322, 323, 324, 325, 326, 150, 164, 169, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346 }; static const uint8_t default_dict_cff_data[] = { // CFF header 1, 0, // format major and minor version 4, // header size 4, // absolute offset size // Name INDEX 0, 1, // one element in index 1, // offset size 1, 14, // offset array '%', 'D', 'E', 'F', 'A', 'U', 'L', 'T', 'D', 'I', 'C', 'T', '%', // Top DICT INDEX 0, 1, // one element in index 1, // offset size 1, 92, // offset array // and the DICT 139, 12, 1, // isFixedPitch false 139, 12, 2, // ItalicAngle 0 39, 12, 3, // UnderlinePosition -100 189, 12, 4, // UnderlineThickness 50 139, 12, 5, // PaintType 0 141, 12, 6, // CharstringType 2 30, 0x0A, 0x00, 0x1F, 139, 139, 30, 0x0A, 0x00, 0x1F, 139, 139, 12, 7, // FontMatrix 0.001 0 0 0.001 0 0 139, 139, 139, 139, 5, // FontBBox 0 0 0 0 139, 12, 8, // StrokeWidth 0 139, 15, // charset 0 139, 16, // Encoding 0 139, 12, 31, // CIDFontVersion 0 139, 12, 32, // CIDFontRevision 0 139, 12, 33, // CIDFontType 0 28, 34, 16, 12, 34, // CIDCount 8720 30, 0x0A, 0x03, 0x96, 0x25, 0xFF, 12, 9, // BlueScale 0.039625 146, 12, 10, // BlueShift 7 140, 12, 11, // BlueFuzz 1 139, 12, 14, // ForceBold false 139, 12, 17, // LanguageGroup 0 30, 0x0A, 0x06, 0xFF, 12, 18, // ExpansionFactor 0.06 139, 12, 19, // initialRandomSeed 0 139, 20, // defaultWidthX 0 139, 21, // nominalWidthX 0 // String INDEX 0, 0, // Gsubr INDEX 0, 0 }; static const Cff::Dict& default_dict() { static Cff cff(String::make_stable((const char*) default_dict_cff_data, sizeof(default_dict_cff_data)), 0, ErrorHandler::default_handler()); return static_cast(cff.font())->top_dict(); } #define POS_GT(pos1, pos2) ((unsigned)(pos1) > (unsigned)(pos2)) Cff::Cff(const String& s, unsigned units_per_em, ErrorHandler* errh) : _data_string(s), _data(reinterpret_cast(_data_string.data())), _len(_data_string.length()), _strings_map(-2), _units_per_em(units_per_em) { static_assert((sizeof(standard_strings) / sizeof(standard_strings[0])) == NSTANDARD_STRINGS, "NSTANDARD_STRINGS defined incorrectly"); static_assert((sizeof(standard_encoding) / sizeof(standard_encoding[0])) == 256, "standard_encoding has wrong size"); static_assert((sizeof(expert_encoding) / sizeof(expert_encoding[0])) == 256, "expert_encoding has wrong size"); _error = parse_header(errh ? errh : ErrorHandler::silent_handler()); } Cff::~Cff() { for (int i = 0; i < _gsubrs_cs.size(); i++) delete _gsubrs_cs[i]; for (int i = 0; i < _fonts.size(); ++i) delete _fonts[i]; } /* * Parsing the file header */ int Cff::parse_header(ErrorHandler *errh) { if (_gsubrs_index.error() >= 0) // already done return 0; // parse header if (_len == 0) return errh->error("not a PostScript-flavored OpenType font"), -EFAULT; if (_len < HEADER_SIZE) return errh->error("CFF file corrupted (too small)"), -EFAULT; if (_data[0] != 1) // major version number return errh->error("bad major version number %d", _data[0]), -ERANGE; int hdrSize = _data[2], offSize = _data[3]; if (hdrSize < 4 || hdrSize > _len || offSize < 1 || offSize > 4) return errh->error("corrupted file header"), -EINVAL; int name_index_pos = hdrSize; // parse name INDEX IndexIterator niter(_data, name_index_pos, _len, errh, "Name INDEX"); if (niter.error() < 0) return niter.error(); _name_index.clear(); for (; niter; niter++) { const uint8_t *d0 = niter[0]; const uint8_t *d1 = niter[1]; if (d0 == d1 || d0[0] == 0) _name_index.push_back(PermString()); else _name_index.push_back(PermString(reinterpret_cast(d0), d1 - d0)); } int top_dict_index_pos = niter.index_end() - _data; // check top DICT INDEX _top_dict_index = IndexIterator(_data, top_dict_index_pos, _len, errh, "Top DICT INDEX"); if (_top_dict_index.error() < 0) return _top_dict_index.error(); else if (_top_dict_index.nitems() != nfonts()) return errh->error("invalid font: Top DICT INDEX has %d elements, but there are %d fonts", _top_dict_index.nitems(), nfonts()), -EINVAL; int string_index_pos = _top_dict_index.index_end() - _data; // check strings INDEX _strings_index = IndexIterator(_data, string_index_pos, _len, errh, "Strings INDEX"); if (_strings_index.error() < 0) return _strings_index.error(); else if (NSTANDARD_STRINGS + _strings_index.nitems() - 1 > MAX_SID) return errh->error("too many strings defined in font"), -EINVAL; _strings.assign(_strings_index.nitems(), PermString()); int global_subr_index_pos = _strings_index.index_end() - _data; // check gsubr INDEX _gsubrs_index = IndexIterator(_data, global_subr_index_pos, _len, errh, "Gsubrs INDEX"); if (_gsubrs_index.error() < 0) return _gsubrs_index.error(); _gsubrs_cs.assign(ngsubrs(), 0); return 0; } int Cff::sid(PermString s) { if (!s) // XXX? return -1; // check standard strings if (standard_permstrings_map["a"] < 0) for (int i = 0; i < NSTANDARD_STRINGS; i++) { if (!standard_permstrings[i]) standard_permstrings[i] = PermString(standard_strings[i]); standard_permstrings_map.insert(standard_permstrings[i], i); } int sid = standard_permstrings_map[s]; if (sid >= 0) return sid; // check user strings sid = _strings_map[s]; if (sid >= -1) return sid; for (int i = 0; i < _strings.size(); i++) if (!_strings[i] && s.length() == _strings_index[i+1] - _strings_index[i] && memcmp(s.c_str(), _strings_index[i], s.length()) == 0) { _strings[i] = s; _strings_map.insert(s, i + NSTANDARD_STRINGS); return i + NSTANDARD_STRINGS; } _strings_map.insert(s, -1); return -1; } String Cff::sid_string(int sid) const { if (sid < 0) return String(); else if (sid < NSTANDARD_STRINGS) return String(sid_permstring(sid)); else { sid -= NSTANDARD_STRINGS; if (sid >= _strings.size()) return String(); else if (_strings[sid]) return String(_strings[sid]); else return String(reinterpret_cast(_strings_index[sid]), _strings_index[sid + 1] - _strings_index[sid]); } } PermString Cff::sid_permstring(int sid) const { if (sid < 0) return PermString(); else if (sid < NSTANDARD_STRINGS) { if (!standard_permstrings[sid]) standard_permstrings[sid] = PermString(standard_strings[sid]); return standard_permstrings[sid]; } else { sid -= NSTANDARD_STRINGS; if (sid >= _strings.size()) return PermString(); else if (_strings[sid]) return _strings[sid]; else { PermString s = PermString(reinterpret_cast(_strings_index[sid]), _strings_index[sid + 1] - _strings_index[sid]); _strings[sid] = s; _strings_map.insert(s, sid + NSTANDARD_STRINGS); return s; } } } Cff::FontParent * Cff::font(PermString font_name, ErrorHandler *errh) { if (!errh) errh = ErrorHandler::silent_handler(); if (!ok()) return errh->error("invalid CFF"), (FontParent *) 0; // search for a font named 'font_name' int findex; for (findex = 0; findex < _name_index.size(); ++findex) { if (_name_index[findex] && (!font_name || font_name == _name_index[findex])) break; } if (findex >= _name_index.size()) { if (!font_name) errh->error("no fonts in CFF"); else errh->error("font %<%s%> not found", font_name.c_str()); return 0; } // return font for (int i = 0; i < _fonts.size(); ++i) if (_fonts[i]->_font_index == findex) return _fonts[i]; int td_offset = _top_dict_index[findex] - _data; int td_length = _top_dict_index[findex + 1] - _top_dict_index[findex]; Dict top_dict(this, td_offset, td_length, errh, "Top DICT"); if (!top_dict.ok()) return 0; Cff::FontParent* fp; if (top_dict.has_first(oROS)) fp = new Cff::CIDFont(this, _name_index[findex], top_dict, errh); else fp = new Cff::Font(this, _name_index[findex], top_dict, errh); fp->_font_index = findex; _fonts.push_back(fp); return fp; } static inline int subr_bias(int charstring_type, int nsubrs) { if (charstring_type == 1) return 0; else if (nsubrs < 1240) return 107; else if (nsubrs < 33900) return 1131; else return 32768; } Charstring * Cff::gsubr(int i) { i += subr_bias(2, ngsubrs()); if (i < 0 || i >= ngsubrs()) return 0; if (!_gsubrs_cs[i]) { const uint8_t *s1 = _gsubrs_index[i]; int slen = _gsubrs_index[i + 1] - s1; String cs = data_string().substring(s1 - data(), slen); if (slen == 0) return 0; else _gsubrs_cs[i] = new Type2Charstring(cs); } return _gsubrs_cs[i]; } /***** * Cff::Charset **/ Cff::Charset::Charset(const Cff *cff, int pos, int nglyphs, int max_sid, ErrorHandler *errh) { assign(cff, pos, nglyphs, max_sid, errh); } void Cff::Charset::assign(const Cff *cff, int pos, int nglyphs, int max_sid, ErrorHandler *errh) { if (!errh) errh = ErrorHandler::silent_handler(); _sids.reserve(nglyphs); if (pos == 0) assign(iso_adobe_charset, sizeof(iso_adobe_charset) / sizeof(int), nglyphs); else if (pos == 1) assign(expert_charset, sizeof(expert_charset) / sizeof(int), nglyphs); else if (pos == 2) assign(expert_subset_charset, sizeof(expert_subset_charset) / sizeof(int), nglyphs); else _error = parse(cff, pos, nglyphs, max_sid, errh); if (_error >= 0) for (int g = 0; g < _sids.size(); g++) { if (_gids[_sids[g]] >= 0) { errh->error("glyph %<%s%> in charset twice", cff->sid_permstring(_sids[g]).c_str()); _error = -EEXIST; } _gids[_sids[g]] = g; } } void Cff::Charset::assign(const int *data, int size, int nglyphs) { if (size < nglyphs) size = nglyphs; _sids.resize(size); memcpy(&_sids[0], data, sizeof(const int) * size); _gids.resize(data[size-1] + 1, -1); _error = 0; } int Cff::Charset::parse(const Cff *cff, int pos, int nglyphs, int max_sid, ErrorHandler *errh) { const uint8_t *data = cff->data(); int len = cff->length(); if (pos + 1 > len) return errh->error("charset position out of range"), -EFAULT; _sids.push_back(0); int actual_max_sid = 0; int format = data[pos]; if (format == 0) { if (pos + 1 + (nglyphs - 1) * 2 > len) return errh->error("charset [format 0] out of range"), -EFAULT; const uint8_t *p = data + pos + 1; for (; _sids.size() < nglyphs; p += 2) { int sid = (p[0] << 8) | p[1]; if (sid > actual_max_sid) actual_max_sid = sid; _sids.push_back(sid); } } else if (format == 1) { const uint8_t *p = data + pos + 1; for (; _sids.size() < nglyphs; p += 3) { if (p + 3 > data + len) return errh->error("charset [format 1] out of range"), -EFAULT; int sid = (p[0] << 8) | p[1]; int n = p[2]; if (sid + n > actual_max_sid) actual_max_sid = sid + n; for (int i = 0; i <= n; i++) _sids.push_back(sid + i); } } else if (format == 2) { const uint8_t *p = data + pos + 1; for (; _sids.size() < nglyphs; p += 4) { if (p + 4 > data + len) return errh->error("charset [format 2] out of range"), -EFAULT; int sid = (p[0] << 8) | p[1]; int n = (p[2] << 8) | p[3]; if (sid + n > actual_max_sid) actual_max_sid = sid + n; for (int i = 0; i <= n; i++) _sids.push_back(sid + i); } } else return errh->error("unknown charset format %d", format), -EINVAL; if (max_sid >= 0 && actual_max_sid > max_sid) return errh->error("charset [format %d] uses bad SID %d", format, actual_max_sid), -EINVAL; _sids.resize(nglyphs); _gids.resize(actual_max_sid + 1, -1); return 0; } /***** * Cff::FDSelect **/ void Cff::FDSelect::assign(const Cff *cff, int pos, int nglyphs, ErrorHandler *errh) { if (!errh) errh = ErrorHandler::silent_handler(); if (_my_fds) delete[] _fds; _fds = 0; _my_fds = false; _nglyphs = nglyphs; _error = parse(cff, pos, nglyphs, errh); } Cff::FDSelect::~FDSelect() { if (_my_fds) delete[] _fds; } int Cff::FDSelect::parse(const Cff *cff, int pos, int nglyphs, ErrorHandler *errh) { const uint8_t *data = cff->data(); int len = cff->length(); if (pos + 1 > len) return errh->error("FDSelect position out of range"), -EFAULT; int format = data[pos]; if (format == 0) { if (pos + 1 + nglyphs > len) return errh->error("FDSelect [format 0] out of range"), -EFAULT; _fds = data + pos + 1; _my_fds = false; return 0; } else if (format == 3) { int nranges = (data[pos+1] << 8) | data[pos+2]; if (pos + 3 + 3*nranges + 2 > len) return errh->error("FDSelect [format 3] out of range"), -EFAULT; const uint8_t *p = data + pos + 3; int last_glyph = (p[3*nranges] << 8) | p[3*nranges + 1]; if (p[0] || p[1] || last_glyph != nglyphs) return errh->error("FDSelect [format 3] bad values"), -EINVAL; _fds = new uint8_t[nglyphs]; _my_fds = true; int curglyph = 0; for (; curglyph < nglyphs; p += 3) { int nextglyph = (p[3] << 8) | p[4]; if (nextglyph > nglyphs || nextglyph < curglyph) return errh->error("FDSelect [format 3] sorting error"), -EINVAL; memset(const_cast(_fds + curglyph), p[2], nextglyph - curglyph); curglyph = nextglyph; } return 0; } else return errh->error("unknown charset format %d", format), -EINVAL; } /***** * Cff::IndexIterator **/ Cff::IndexIterator::IndexIterator(const uint8_t *data, int pos, int len, ErrorHandler *errh, const char *index_name) : _contents(0), _offset(0), _last_offset(0) { if (!errh) errh = ErrorHandler::silent_handler(); // check header int nitems = 0; if (POS_GT(pos + 2, len)) { errh->error("%s: position out of range", index_name); _offsize = -EFAULT; } else if (data[pos] == 0 && data[pos + 1] == 0) { _contents = data + pos + 2; _offsize = 0; } else if (POS_GT(pos + 3, len)) { errh->error("%s: position out of range", index_name); _offsize = -EFAULT; } else if ((_offsize = data[pos + 2]), (_offsize < 1 || _offsize > 4)) { errh->error("%s: offset size %d out of range", index_name, _offsize); _offsize = -EINVAL; } else { nitems = (data[pos] << 8) | data[pos + 1]; if (POS_GT(pos + 3 + (nitems + 1) * _offsize, len)) { errh->error("%s: data out of range", index_name); _offsize = -EFAULT; } else { _offset = data + pos + 3; _last_offset = _offset + nitems * _offsize; _contents = _last_offset + _offsize - 1; } } // check items in offset array uint32_t max_doff_allowed = len - (pos + 2 + (nitems + 1) * _offsize); uint32_t last_doff = 1; for (const uint8_t *o = _offset; o <= _last_offset && _offsize > 0; o += _offsize) { uint32_t doff = offset_at(o); if (doff > max_doff_allowed) { errh->error("%s: element out of range", index_name); _offsize = -EFAULT; } else if (doff < last_doff) { errh->error("%s: garbled elements", index_name); break; } last_doff = doff; } } const uint8_t * Cff::IndexIterator::index_end() const { if (_offsize <= 0) return _contents; else return _contents + offset_at(_last_offset); } int Cff::IndexIterator::nitems() const { if (_offsize <= 0) return 0; else return (_last_offset - _offset) / _offsize; } /***** * Cff::Dict **/ Cff::Dict::Dict() : _cff(0), _pos(0), _error(-ENOENT) { } Cff::Dict::Dict(Cff *cff, int pos, int dict_len, ErrorHandler *errh, const char *dict_name) { assign(cff, pos, dict_len, errh, dict_name); } int Cff::Dict::assign(Cff *cff, int pos, int dict_len, ErrorHandler *errh, const char *dict_name) { _cff = cff; _pos = pos; _operators.clear(); _pointers.clear(); _operands.clear(); if (!errh) errh = ErrorHandler::silent_handler(); const uint8_t *data = cff->data() + pos; const uint8_t *end_data = data + dict_len; _pointers.push_back(0); while (data < end_data) switch (data[0]) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: _operators.push_back(data[0]); _pointers.push_back(_operands.size()); data++; break; case 22: case 23: case 24: case 25: case 26: case 27: case 31: case 255: // reserved errh->error("%s: reserved operator %d", dict_name, data[0]); return (_error = -ERANGE); case 12: if (data + 1 >= end_data) goto runoff; _operators.push_back(32 + data[1]); _pointers.push_back(_operands.size()); data += 2; break; case 28: { if (data + 2 >= end_data) goto runoff; int16_t val = (data[1] << 8) | data[2]; _operands.push_back(val); data += 3; break; } case 29: { if (data + 4 >= end_data) goto runoff; int32_t val = (data[1] << 24) | (data[2] << 16) | (data[3] << 8) | data[4]; _operands.push_back(val); data += 5; break; } case 30: { char buf[1024]; int pos = 0; if (data + 1 >= end_data) goto runoff; for (data++; data < end_data && pos < 1020; data++) { int d = *data; for (int i = 0; i < 2; i++, d <<= 4) { int digit = (d >> 4) & 0xF; switch (digit) { case 10: buf[pos++] = '.'; break; case 11: buf[pos++] = 'E'; break; case 12: buf[pos++] = 'E'; buf[pos++] = '-'; break; case 13: errh->error("%s: bad digit in real number", dict_name); goto invalid; case 14: buf[pos++] = '-'; break; case 15: goto found; default: buf[pos++] = digit + '0'; break; } } } // number not found goto runoff; found: char *endptr; buf[pos] = '\0'; _operands.push_back(strtod(buf, &endptr)); if (*endptr) { errh->error("%s: real number syntax error", dict_name); goto invalid; } data++; break; } case 247: case 248: case 249: case 250: { if (data + 1 >= end_data) goto runoff; int val = ((data[0] - 247) << 8) + data[1] + 108; _operands.push_back(val); data += 2; break; } case 251: case 252: case 253: case 254: { if (data + 1 >= end_data) goto runoff; int val = -((data[0] - 251) << 8) - data[1] - 108; _operands.push_back(val); data += 2; break; } default: _operands.push_back(data[0] - 139); data++; break; } // not closed by an operator? if (_pointers.back() != _operands.size()) { errh->error("%s: not closed by an operator", dict_name); goto invalid; } return (_error = 0); runoff: errh->error("%s: runoff end of DICT", dict_name); return (_error = -EFAULT); invalid: return (_error = -EINVAL); } int Cff::Dict::check(bool is_private, ErrorHandler *errh, const char *dict_name) const { if (!errh) errh = ErrorHandler::silent_handler(); int before_nerrors = errh->nerrors(); // keep track of operator reuse Vector operators_used; for (int i = 0; i < _operators.size(); i++) { int arity = _pointers[i+1] - _pointers[i]; double num = (arity == 0 ? 0 : _operands[_pointers[i]]); double truncnum = floor(num); int op = _operators[i]; int type = (op > oLastOperator ? tNone : operator_types[op]); // check reuse if (op >= operators_used.size()) operators_used.resize(op + 1, 0); if (operators_used[op] && (type & tTypeMask) != tNone) errh->error("%s: operator %<%s%> specified twice", dict_name, operator_names[op]); operators_used[op]++; // check data switch (type & tTypeMask) { case tNone: if (op >= 32) errh->warning("%s: unknown operator %<12 %d%>", dict_name, op - 32); else errh->warning("%s: unknown operator %<%d%>", dict_name, op); continue; case tSID: if (arity != 1 || num != truncnum || num < 0 || num > _cff->max_sid()) goto bad_data; break; case tFontNumber: if (arity != 1 || num != truncnum || num < 0 || num >= _cff->nfonts()) goto bad_data; break; case tBoolean: if (arity != 1) goto bad_data; else if (num != 0 && num != 1) errh->warning("%s: data for Boolean operator %<%s%> not 0 or 1", dict_name, operator_names[op]); break; case tNumber: if (arity != 1) goto bad_data; break; case tOffset: if (arity != 1 || num != truncnum || num < 0 || num >= _cff->length()) goto bad_data; break; case tLocalOffset: if (arity != 1 || num != truncnum || _pos + num < 0 || _pos + num >= _cff->length()) goto bad_data; break; case tPrivateType: { if (arity != 2 || num != truncnum || num < 0) goto bad_data; double off = _operands[_pointers[i] + 1]; if (off < 0 || off + num > _cff->length()) goto bad_data; break; } case tArray2: case tArray3: case tArray4: case tArray5: case tArray6: if (arity != (type & tTypeMask) - tArray2 + 2) goto bad_data; break; case tArray: break; } // check dict location if (((type & tPrivate) != 0) != is_private) errh->warning("%s: operator %<%s%> in wrong DICT", dict_name, operator_names[op]); continue; bad_data: errh->error("%s: bad data for operator %<%s%>", dict_name, operator_names[op]); } return (errh->nerrors() != before_nerrors ? -1 : 0); } bool Cff::Dict::has(DictOperator op) const { for (int i = 0; i < _operators.size(); i++) if (_operators[i] == op) return true; return false; } bool Cff::Dict::xvalue(DictOperator op, Vector &out) const { out.clear(); for (int i = 0; i < _operators.size(); i++) if (_operators[i] == op) { for (int j = _pointers[i]; j < _pointers[i+1]; j++) out.push_back(_operands[j]); return true; } return false; } bool Cff::Dict::xvalue(DictOperator op, int *val) const { for (int i = 0; i < _operators.size(); i++) if (_operators[i] == op && _pointers[i] + 1 == _pointers[i+1]) { *val = (int) _operands[_pointers[i]]; return true; } return false; } bool Cff::Dict::xvalue(DictOperator op, double *val) const { for (int i = 0; i < _operators.size(); i++) if (_operators[i] == op && _pointers[i] + 1 == _pointers[i+1]) { *val = _operands[_pointers[i]]; return true; } return false; } bool Cff::Dict::value(DictOperator op, Vector &out) const { return xvalue(op, out) || default_dict().xvalue(op, out); } bool Cff::Dict::value(DictOperator op, int *val) const { return xvalue(op, val) || default_dict().xvalue(op, val); } bool Cff::Dict::value(DictOperator op, double *val) const { return xvalue(op, val) || default_dict().xvalue(op, val); } void Cff::Dict::unparse(ErrorHandler *errh, const char *dict_name) const { StringAccum sa; for (int i = 0; i < _operators.size(); i++) { sa.clear(); if (_pointers[i] + 1 == _pointers[i+1]) sa << _operands[_pointers[i]]; else { sa << "["; for (int j = _pointers[i]; j < _pointers[i+1]; j++) sa << _operands[j] << ' '; sa.pop_back(); sa << "]"; } errh->message("%s: %s %s", dict_name, operator_names[_operators[i]], sa.c_str()); } } /***** * CffFontParent **/ static int handle_private(Cff *cff, const Cff::Dict &top_dict, Cff::Dict &private_dict, double &default_width_x, double &nominal_width_x, Cff::IndexIterator &subrs_index, Vector &subrs_cs, ErrorHandler *errh) { Vector private_info; top_dict.value(Cff::oPrivate, private_info); int private_offset = (int) private_info[1]; private_dict.assign(cff, private_offset, (int) private_info[0], errh, "Private DICT"); if (private_dict.error() < 0) return private_dict.error(); else if (private_dict.check(true, errh, "Private DICT") < 0) return -EINVAL; //private_dict.unparse(errh, "Private DICT"); private_dict.value(Cff::oDefaultWidthX, &default_width_x); private_dict.value(Cff::oNominalWidthX, &nominal_width_x); if (private_dict.has(Cff::oSubrs)) { int subrs_offset = 0; private_dict.value(Cff::oSubrs, &subrs_offset); subrs_index = Cff::IndexIterator(cff->data(), private_offset + subrs_offset, cff->length(), errh, "Subrs INDEX"); if (subrs_index.error() < 0) return subrs_index.error(); } subrs_cs.assign(subrs_index.nitems(), 0); return 0; } Cff::FontParent::FontParent(Cff* cff) : CharstringProgram(cff->units_per_em()), _cff(cff), _error(-1) { } Charstring * Cff::FontParent::charstring(const IndexIterator &iiter, int which) const { const uint8_t *s1 = iiter[which]; int slen = iiter[which + 1] - s1; String cs = _cff->data_string().substring(s1 - _cff->data(), slen); if (slen == 0) return 0; else if (_charstring_type == 1) return new Type1Charstring(cs); else return new Type2Charstring(cs); } Charstring * Cff::FontParent::gsubr(int i) const { return _cff->gsubr(i); } int Cff::FontParent::gsubr_bias() const { return Efont::subr_bias(2, ngsubrs_x()); } /***** * CffFont **/ Cff::Font::Font(Cff *cff, PermString font_name, const Dict &top_dict, ErrorHandler *errh) : ChildFont(cff, 0, 2, top_dict, errh), _font_name(font_name), _t1encoding(0) { assert(!_top_dict.has_first(oROS)); if (_error < 0) return; // extract CharStrings // must use xvalue because we could be creating the default dict! int charstrings_offset = 0; _top_dict.xvalue(oCharStrings, &charstrings_offset); _charstrings_index = Cff::IndexIterator(cff->data(), charstrings_offset, cff->length(), errh, "CharStrings INDEX"); if (_charstrings_index.error() < 0) { _error = _charstrings_index.error(); return; } _charstrings_cs.assign(_charstrings_index.nitems(), 0); int charset = 0; _top_dict.xvalue(oCharset, &charset); _charset.assign(cff, charset, _charstrings_index.nitems(), cff->max_sid(), errh); if (_charset.error() < 0) { _error = _charset.error(); return; } int Encoding = 0; _top_dict.xvalue(oEncoding, &Encoding); if (parse_encoding(Encoding, errh) < 0) return; // success! _error = 0; } Cff::Font::~Font() { for (int i = 0; i < _charstrings_cs.size(); i++) delete _charstrings_cs[i]; delete _t1encoding; } int Cff::Font::parse_encoding(int pos, ErrorHandler *errh) { _encoding_pos = pos; for (int i = 0; i < 256; i++) _encoding[i] = 0; // check for standard encodings if (pos == 0) return assign_standard_encoding(standard_encoding); else if (pos == 1) return assign_standard_encoding(expert_encoding); // otherwise, a custom encoding const uint8_t *data = _cff->data(); int len = _cff->length(); if (pos + 1 > len) return errh->error("Encoding position out of range"), -EFAULT; bool supplemented = (data[pos] & 0x80) != 0; int format = (data[pos] & 0x7F); int retval = 0; int endpos, g = 1; if (format == 0) { endpos = pos + 2 + data[pos + 1]; if (endpos > len) return errh->error("Encoding[0] out of range"), -EFAULT; const uint8_t *p = data + pos + 2; int n = data[pos + 1]; for (; g <= n; g++, p++) { int e = p[0]; if (_encoding[e]) retval = 1; _encoding[e] = g; } } else if (format == 1) { endpos = pos + 2 + data[pos + 1] * 2; if (endpos > len) return errh->error("Encoding[1] out of range"), -EFAULT; const uint8_t *p = data + pos + 2; int n = data[pos + 1]; for (int i = 0; i < n; i++, p += 2) { int first = p[0]; int nLeft = p[1]; for (int e = first; e <= first + nLeft; e++) { if (_encoding[e]) retval = 1; _encoding[e] = g++; } } } else return errh->error("unknown Encoding format %d", format), -EINVAL; if (g > _charset.nglyphs()) return errh->error("Encoding glyph %d out of range", g), -EINVAL; // check supplements if (supplemented) { if (endpos + data[endpos] * 3 > len) return -EINVAL; const uint8_t *p = data + endpos + 1; int n = data[endpos]; for (int i = 0; i < n; i++, p += 3) { int e = p[0]; int s = (p[1] << 8) | p[2]; int g = _charset.sid_to_gid(s); if (_encoding[e]) retval = 1; if (g < 0 || g >= _charset.nglyphs()) return errh->error("Encoding glyph %d out of range", g), -EINVAL; _encoding[e] = g; } } // successfully done return retval; } int Cff::Font::assign_standard_encoding(const int *standard_encoding) { for (int i = 0; i < 256; i++) _encoding[i] = _charset.sid_to_gid(standard_encoding[i]); return 0; } void Cff::Font::font_matrix(double matrix[6]) const { Vector t1d_matrix; if (dict_value(oFontMatrix, t1d_matrix) && t1d_matrix.size() == 6) memcpy(&matrix[0], &t1d_matrix[0], sizeof(double) * 6); else { matrix[0] = matrix[3] = 0.001; matrix[1] = matrix[2] = matrix[4] = matrix[5] = 0; } } PermString Cff::Font::glyph_name(int gid) const { if (gid >= 0 && gid < nglyphs()) return _cff->sid_permstring(_charset.gid_to_sid(gid)); else return PermString(); } void Cff::Font::glyph_names(Vector &gnames) const { gnames.resize(nglyphs()); for (int i = 0; i < nglyphs(); i++) gnames[i] = _cff->sid_permstring(_charset.gid_to_sid(i)); } Charstring * Cff::Font::glyph(int gid) const { if (gid < 0 || gid >= nglyphs()) return 0; if (!_charstrings_cs[gid]) _charstrings_cs[gid] = charstring(_charstrings_index, gid); return _charstrings_cs[gid]; } Charstring * Cff::Font::glyph(PermString name) const { int gid = _charset.sid_to_gid(_cff->sid(name)); if (gid < 0) return 0; if (!_charstrings_cs[gid]) _charstrings_cs[gid] = charstring(_charstrings_index, gid); return _charstrings_cs[gid]; } int Cff::Font::glyphid(PermString name) const { return _charset.sid_to_gid(_cff->sid(name)); } Type1Encoding * Cff::Font::type1_encoding() const { if (_encoding_pos == 0) return Type1Encoding::standard_encoding(); if (!_t1encoding) _t1encoding = type1_encoding_copy(); return _t1encoding; } Type1Encoding * Cff::Font::type1_encoding_copy() const { if (_encoding_pos == 0) return Type1Encoding::standard_encoding(); Type1Encoding *e = new Type1Encoding; for (int i = 0; i < 256; i++) if (_encoding[i]) e->put(i, _cff->sid_permstring(_charset.gid_to_sid(_encoding[i]))); return e; } bool Cff::Font::dict_has(DictOperator op) const { return dict_of(op).has(op); } String Cff::Font::dict_string(DictOperator op) const { Vector vec; dict_of(op).value(op, vec); if (vec.size() == 1 && vec[0] >= 0 && vec[0] <= _cff->max_sid()) return _cff->sid_string((int) vec[0]); else return String(); } /***** * Cff::CIDFont **/ Cff::CIDFont::CIDFont(Cff *cff, PermString font_name, const Dict &top_dict, ErrorHandler *errh) : FontParent(cff), _font_name(font_name), _top_dict(top_dict) { assert(_top_dict.has_first(oROS)); // parse top DICT _error = -EINVAL; if (_top_dict.check(false, errh, "Top DICT") < 0) return; else if (!_top_dict.has(oCharStrings)) { errh->error("font has no CharStrings dictionary"); return; } //_top_dict.unparse(errh, "Top DICT"); // extract offsets and information from TOP DICT _top_dict.value(oCharstringType, &_charstring_type); if (_charstring_type != 1 && _charstring_type != 2) { errh->error("unknown CharString type %d", _charstring_type); return; } int charstrings_offset = 0; _top_dict.value(oCharStrings, &charstrings_offset); _charstrings_index = Cff::IndexIterator(cff->data(), charstrings_offset, cff->length(), errh, "CharStrings INDEX"); if (_charstrings_index.error() < 0) { _error = _charstrings_index.error(); return; } _charstrings_cs.assign(_charstrings_index.nitems(), 0); int charset = 0; _top_dict.value(oCharset, &charset); _charset.assign(cff, charset, _charstrings_index.nitems(), -1, errh); if (_charset.error() < 0) { _error = _charset.error(); return; } // extract information about child fonts int fdarray_offset = 0; if (!_top_dict.value(oFDArray, &fdarray_offset)) { errh->error("CID-keyed font missing FDArray"); return; } IndexIterator fdarray_index(cff->data(), fdarray_offset, cff->length(), errh, "FDArray INDEX"); for (; fdarray_index; fdarray_index++) { Dict d(cff, fdarray_index[0] - cff->data(), fdarray_index[1] - fdarray_index[0], errh, "Top DICT"); if (!d.ok() || d.check(false, errh, "Top DICT") < 0) { _error = d.error(); return; } _child_fonts.push_back(new ChildFont(cff, this, _charstring_type, d, errh)); if (!_child_fonts.back()->ok()) return; } int fdselect_offset = 0; if (!_top_dict.value(oFDSelect, &fdselect_offset)) { errh->error("CID-keyed font missing FDSelect"); return; } _fdselect.assign(cff, fdselect_offset, _charstrings_cs.size(), errh); if (_fdselect.error() < 0) return; // success! _error = 0; set_parent_program(true); } Cff::CIDFont::~CIDFont() { for (int i = 0; i < _charstrings_cs.size(); i++) delete _charstrings_cs[i]; for (int i = 0; i < _child_fonts.size(); i++) delete _child_fonts[i]; } void Cff::CIDFont::font_matrix(double matrix[6]) const { // XXX matrix[0] = matrix[3] = 0.001; matrix[1] = matrix[2] = matrix[4] = matrix[5] = 0; } const CharstringProgram * Cff::CIDFont::child_program(int gid) const { int fd = _fdselect.gid_to_fd(gid); if (fd >= 0 && fd < _child_fonts.size()) return _child_fonts.at_u(fd); else return 0; } PermString Cff::CIDFont::glyph_name(int gid) const { if (gid >= 0 && gid < nglyphs()) return permprintf("#%d", _charset.gid_to_sid(gid)); else return PermString(); } void Cff::CIDFont::glyph_names(Vector &gnames) const { gnames.resize(nglyphs()); for (int i = 0; i < nglyphs(); i++) gnames[i] = permprintf("#%d", _charset.gid_to_sid(i)); } Charstring * Cff::CIDFont::glyph(int gid) const { if (gid < 0 || gid >= nglyphs()) return 0; if (!_charstrings_cs[gid]) _charstrings_cs[gid] = charstring(_charstrings_index, gid); return _charstrings_cs[gid]; } int Cff::CIDFont::glyphid(PermString name) const { if (name.length() <= 1 || name[0] != '#' || !isdigit((unsigned char) name[1])) return -1; char *endptr; long cid = strtol(name.c_str() + 1, &endptr, 10); if (*endptr != 0) return -1; return _charset.sid_to_gid(cid); } Charstring * Cff::CIDFont::glyph(PermString name) const { return CIDFont::glyph(CIDFont::glyphid(name)); } /***** * ChildFont **/ Cff::ChildFont::ChildFont(Cff *cff, Cff::CIDFont *parent, int charstring_type, const Dict &top_dict, ErrorHandler *errh) : FontParent(cff), _parent(parent), _top_dict(top_dict) { if (!errh) errh = ErrorHandler::silent_handler(); if (!cff->ok() || !_top_dict.ok()) { errh->error("invalid CFF"); _error = -EINVAL; return; } // extract offsets and information from TOP DICT _charstring_type = charstring_type; _top_dict.value(oCharstringType, &_charstring_type); if (_charstring_type != 1 && _charstring_type != 2) { errh->error("unknown CharString type %d", _charstring_type); return; } // extract information from Private DICT if (_top_dict.has(oPrivate) && (_error = handle_private(cff, _top_dict, _private_dict, _default_width_x, _nominal_width_x, _subrs_index, _subrs_cs, errh)) < 0) return; // success! _error = 0; } Cff::ChildFont::~ChildFont() { for (int i = 0; i < _subrs_cs.size(); i++) delete _subrs_cs[i]; } Charstring * Cff::ChildFont::charstring(const IndexIterator &iiter, int which) const { const uint8_t *s1 = iiter[which]; int slen = iiter[which + 1] - s1; String cs = _cff->data_string().substring(s1 - _cff->data(), slen); if (slen == 0) return 0; else if (_charstring_type == 1) return new Type1Charstring(cs); else return new Type2Charstring(cs); } Charstring * Cff::ChildFont::subr(int i) const { i += Efont::subr_bias(_charstring_type, nsubrs_x()); if (i < 0 || i >= nsubrs_x()) return 0; if (!_subrs_cs[i]) _subrs_cs[i] = charstring(_subrs_index, i); return _subrs_cs[i]; } int Cff::ChildFont::subr_bias() const { return Efont::subr_bias(_charstring_type, nsubrs_x()); } double Cff::ChildFont::global_width_x(bool is_nominal) const { return (is_nominal ? _nominal_width_x : _default_width_x); } } lcdf-typetools-2.108/libefont/amfm.cc0000644000175000017500000005262413423375327014470 00000000000000// -*- related-file-name: "../include/efont/amfm.hh" -*- /* amfm.{cc,hh} -- Adobe Multiple-Master Font Metrics * * Copyright (c) 1998-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include namespace Efont { AmfmMetrics::AmfmMetrics(MetricsFinder *finder) : _finder(finder), _fdv(fdLast, UNKDOUBLE), _nmasters(-1), _naxes(-1), _masters(0), _mmspace(0), _primary_fonts(0), _sanity_afm(0), _uses(0) { } AmfmMetrics::~AmfmMetrics() { assert(_uses == 0); for (int m = 0; m < _nmasters; m++) if (_masters[m].afm) _masters[m].afm->unuse(); delete[] _masters; delete _mmspace; while (_primary_fonts) { AmfmPrimaryFont *pf = _primary_fonts; _primary_fonts = _primary_fonts->next; delete pf; } } bool AmfmMetrics::sanity(ErrorHandler *errh) const { if (!_mmspace) { errh->error("AMFM sanity: no multiple master interpolation information"); return false; } bool ok = true; for (int m = 0; m < _nmasters; m++) if (!_masters[m].font_name || _masters[m].weight_vector.size() != _nmasters) { errh->error("AMFM sanity: no information for master %d", m); ok = false; } if (!_mmspace->check(errh)) ok = false; return ok; } int AmfmMetrics::primary_label_value(int ax, PermString label) const { assert(ax >= 0 && ax < _naxes); for (AmfmPrimaryFont *pf = _primary_fonts; pf; pf = pf->next) { if (pf->labels[ax] == label) return pf->design_vector[ax]; } return -1; } inline static bool strcompat(PermString a, PermString b) { return !a || !b || a == b; } Metrics * AmfmMetrics::master(int m, ErrorHandler *errh) { AmfmMaster &master = _masters[m]; if (!master.loaded) { master.loaded = true; DirectoryMetricsFinder directory_finder(_directory); _finder->add_finder(&directory_finder); Metrics *afm = _finder->find_metrics(master.font_name); if (!afm) { if (errh) errh->error("%s: can't find AFM file for master `%s'", _font_name.c_str(), master.font_name.c_str()); } else if (!strcompat(afm->font_name(), master.font_name) || !strcompat(afm->family(), master.family) || !strcompat(afm->full_name(), master.full_name) || !strcompat(afm->version(), master.version)) { if (errh) errh->error("%s: AFM for master `%s' doesn't match AMFM", _font_name.c_str(), master.font_name.c_str()); } else if (!_sanity_afm) { master.afm = afm; _sanity_afm = afm; afm->use(); } else { PairProgram *sanity_pairp = _sanity_afm->pair_program(); PairProgram *pairp = afm->pair_program(); char buf[1024]; buf[0] = 0; if (afm->nglyphs() != _sanity_afm->nglyphs()) sprintf(buf, "glyph count (%d vs. %d)", afm->nglyphs(), _sanity_afm->nglyphs()); if (afm->nfd() != _sanity_afm->nfd()) sprintf(buf, "fd count (%d vs. %d)", afm->nfd(), _sanity_afm->nfd()); if (afm->nkv() != _sanity_afm->nkv()) sprintf(buf, "kv count (%d vs. %d)", afm->nkv(), _sanity_afm->nkv()); if (pairp->op_count() != sanity_pairp->op_count()) sprintf(buf, "pair op count (%d vs. %d)", pairp->op_count(), sanity_pairp->op_count()); if (!buf[0]) { master.afm = afm; afm->use(); } else if (errh) errh->error("%s: AFM for master `%s' failed sanity checks (%s)", _font_name.c_str(), master.font_name.c_str(), buf); } } return master.afm; } AmfmPrimaryFont * AmfmMetrics::find_primary_font(const Vector &design_vector) const { assert(design_vector.size() == _naxes); for (AmfmPrimaryFont *pf = _primary_fonts; pf; pf = pf->next) { for (int a = 0; a < _naxes; a++) if ((int)design_vector[a] != pf->design_vector[a]) goto loser; return pf; loser: ; } return 0; } Metrics * AmfmMetrics::interpolate(const Vector &design_vector, const Vector &weight_vector, ErrorHandler *errh) { assert(design_vector.size() == _naxes); assert(weight_vector.size() == _nmasters); // FIXME: check masters for correspondence. /* 0. * Make sure all necessary AFMs have been loaded. */ int m; for (m = 0; m < _nmasters; m++) if (weight_vector[m]) if (!master(m, errh)) return 0; /* 1. * Use the design vector to generate new FontName and FullName. */ AmfmPrimaryFont *pf = find_primary_font(design_vector); // The primary font is useless to us if it doesn't have axis labels. if (pf && !pf->labels.size()) pf = 0; StringAccum font_name_sa, full_name_sa; font_name_sa << _font_name; full_name_sa << _full_name; for (int a = 0; a < _naxes; a++) { double dv = design_vector[a]; font_name_sa << '_' << dv; full_name_sa << (a == 0 ? '_' : ' ') << dv; PermString label; if (pf) label = pf->labels[a]; if (!label) label = _mmspace->axis_abbreviation(a); if (label) full_name_sa << ' ' << label; } // Multiple master fonts require an underscore AFTER the font name too font_name_sa << '_'; /* 2. * Set up the new AFM with the special constructor. */ // Find the first master with a non-zero component. for (m = 0; m < _nmasters && weight_vector[m] == 0; m++) ; Metrics *afm = new Metrics(font_name_sa.c_str(), full_name_sa.c_str(), *_masters[m].afm); if (MetricsXt *xt = _masters[m].afm->find_xt("AFM")) { AfmMetricsXt *new_xt = new AfmMetricsXt((AfmMetricsXt &)*xt); afm->add_xt(new_xt); } /* 2. * Interpolate the old AFM data into the new. */ afm->interpolate_dimens(*_masters[m].afm, weight_vector[m], false); for (m++; m < _nmasters; m++) if (weight_vector[m]) afm->interpolate_dimens(*_masters[m].afm, weight_vector[m], true); return afm; } /***** * AmfmReader **/ AmfmReader::AmfmReader(AfmParser &afmp, AmfmMetrics *amfm, ErrorHandler *errh) : _amfm(amfm), _finder(amfm->_finder), _l(afmp), _mmspace(amfm->_mmspace) { _errh = errh ? errh : ErrorHandler::silent_handler(); } AmfmMetrics * AmfmReader::read(Slurper &slurper, MetricsFinder *finder, ErrorHandler *errh) { AfmParser parser(slurper); if (!parser.ok()) return 0; AmfmMetrics *amfm = new AmfmMetrics(finder); AmfmReader reader(parser, amfm, errh); if (!reader.read()) { delete amfm; return 0; } else return amfm; } AmfmMetrics * AmfmReader::read(const Filename &fn, MetricsFinder *finder, ErrorHandler *errh) { Slurper slurper(fn); return read(slurper, finder, errh); } void AmfmReader::add_amcp_file(Slurper &slurper, AmfmMetrics *amfm, ErrorHandler *errh) { AfmParser parser(slurper); if (!parser.ok()) return; AmfmReader reader(parser, amfm, errh); reader.read_amcp_file(); } void AmfmReader::lwarning(const char *format, ...) const { va_list val; va_start(val, format); _errh->xmessage(_l.landmark(), ErrorHandler::e_warning, format, val); va_end(val); } void AmfmReader::lerror(const char *format, ...) const { va_list val; va_start(val, format); _errh->xmessage(_l.landmark(), ErrorHandler::e_error, format, val); va_end(val); } void AmfmReader::no_match_warning(const char *context) const { // keyword() will fail (and a warning won't get printed) only if the string // is all whitespace, which the spec allows PermString keyword = _l.keyword(); if (!keyword) return; if (_l.key_matched()) { lwarning(context ? "bad `%s' command in %s:" : "bad `%s' command:", keyword.c_str(), context); lwarning("field %d %s", _l.fail_field(), _l.message().c_str()); } else lwarning(context ? "unknown command `%s' in %s" : "unknown command `%s'", keyword.c_str(), context); _l.clear_message(); } void AmfmReader::check_mmspace() { if (!_mmspace && _amfm->_naxes >= 0 && _amfm->_nmasters >= 0 && _amfm->_font_name) { _mmspace = _amfm->_mmspace = new MultipleMasterSpace(_amfm->_font_name, _amfm->_naxes, _amfm->_nmasters); } } bool AmfmReader::read() { assert(_amfm != 0); _mmspace = _amfm->_mmspace; AfmParser &l = _l; _amfm->_directory = l.filename().directory(); // First, read all opening comments into an array so we can print them out // later. PermString comment; while (l.next_line()) { if (l.isall("Comment %+s", &comment)) _amfm->_opening_comments.push_back(comment); else if (l.isall("StartMasterFontMetrics %g", (double *)0)) ; else { l.save_line(); break; } } int master = 0, axis = 0; while (l.next_line()) switch (l[0]) { case 'A': if (l.isall("Ascender %g", &fd( fdAscender ))) break; if (l.isall("Axes %d", &_amfm->_naxes)) { check_mmspace(); break; } goto invalid; case 'B': if (l.is("BlendDesignPositions")) { read_positions(); break; } if (l.is("BlendDesignMap")) { read_normalize(); break; } if (l.is("BlendAxisTypes")) { read_axis_types(); break; } goto invalid; case 'C': if (l.isall("CapHeight %g", &fd( fdCapHeight ))) break; if (l.is("Comment")) break; goto invalid; case 'D': if (l.isall("Descender %g", &fd( fdDescender ))) break; goto invalid; case 'E': if (l.isall("EncodingScheme %+s", &_amfm->_encoding_scheme)) break; if (l.isall("EndMasterFontMetrics")) goto done; goto invalid; case 'F': if (l.isall("FontName %+s", &_amfm->_font_name)) { check_mmspace(); break; } if (l.isall("FullName %+s", &_amfm->_full_name)) break; if (l.isall("FamilyName %+s", &_amfm->_family)) break; if (l.isall("FontBBox %g %g %g %g", &fd( fdFontBBllx ), &fd( fdFontBBlly ), &fd( fdFontBBurx ), &fd( fdFontBBury ))) break; goto invalid; case 'I': if (l.isall("IsFixedPitch %b", (bool *)0)) break; if (l.isall("ItalicAngle %g", &fd( fdItalicAngle ))) break; goto invalid; case 'M': if (l.isall("Masters %d", &_amfm->_nmasters)) { check_mmspace(); break; } goto invalid; case 'N': if (l.isall("Notice %+s", &_amfm->_notice)) break; goto invalid; case 'S': if (l.isall("StartAxis")) { read_axis(axis++); break; } if (l.isall("StartMaster")) { read_master(master++); break; } if (l.isall("StartPrimaryFonts %d", (int *)0)) { read_primary_fonts(); break; } if (l.isall("StartConversionPrograms %d %d", (int *)0, (int *)0)) { read_conversion_programs(); break; } if (l.isall("StartMasterFontMetrics %g", (double *)0)) break; goto invalid; case 'U': if (l.isall("UnderlinePosition %g", &fd( fdUnderlinePosition ))) break; else if (l.isall("UnderlineThickness %g", &fd( fdUnderlineThickness ))) break; goto invalid; case 'V': if (l.isall("Version %+s", &_amfm->_version)) break; goto invalid; case 'W': if (l.isall("Weight %+s", &_amfm->_weight)) break; if (l.is("WeightVector")) { Vector wv; if (!read_simple_array(wv) || !_mmspace) lerror("bad WeightVector"); else _mmspace->set_weight_vector(wv); break; } goto invalid; case 'X': if (l.isall("XHeight %g", &fd( fdXHeight ))) break; goto invalid; default: invalid: no_match_warning(); } done: if (!_mmspace) { _errh->error("`%s' is not an AMFM file", String(_l.landmark().file()).c_str()); return false; } LandmarkErrorHandler pin_errh(_errh, _l.landmark()); if (!_amfm->sanity(&pin_errh)) { _errh->lerror(_l.landmark().whole_file(), "bad AMFM file (missing or inconsistent information)"); return false; } if (!_mmspace->check_intermediate() && _l.filename().directory()) { String name = l.filename().base() + ".amcp"; Slurper slurp(_l.filename().from_directory(name)); add_amcp_file(slurp, _amfm, _errh); } return true; } void AmfmReader::read_amcp_file() { int lines_read = 0; while (_l.next_line()) { lines_read++; switch (_l[0]) { case 'C': if (_l.is("Comment")) break; goto invalid; case 'S': if (_l.isall("StartConversionPrograms %d %d", (int *)0, (int *)0)) { read_conversion_programs(); break; } goto invalid; default: invalid: no_match_warning("AMCP file"); } } if (_mmspace && !_mmspace->ndv() && !_mmspace->cdv() && lines_read) lwarning("no conversion programs in .amcp file"); } bool AmfmReader::read_simple_array(Vector &vec) const { if (!_l.is("[")) return false; vec.clear(); double d; while (_l.is("%g", &d)) vec.push_back(d); return _l.is("]"); } void AmfmReader::read_positions() const { if (nmasters() < 2 || naxes() < 1) return; Vector positions; if (!_l.is("[") || !_mmspace) goto error; for (int i = 0; i < nmasters(); i++) { positions.push_back(NumVector()); if (!read_simple_array(positions.back())) goto error; } if (!_l.is("]")) goto error; _mmspace->set_master_positions(positions); return; error: lerror("bad BlendDesignPositions"); } void AmfmReader::read_normalize() const { if (naxes() < 1) return; Vector normalize_in, normalize_out; if (!_l.is("[") || !_mmspace) goto error; for (int a = 0; a < naxes(); a++) { if (!_l.is("[")) goto error; normalize_in.push_back(NumVector()); normalize_out.push_back(NumVector()); double v1, v2; while (_l.is("[-%g %g-]", &v1, &v2)) { normalize_in[a].push_back(v1); normalize_out[a].push_back(v2); } if (!_l.is("]")) goto error; } if (!_l.is("]")) goto error; _mmspace->set_normalize(normalize_in, normalize_out); return; error: lerror("bad BlendDesignPositions"); } void AmfmReader::read_axis_types() const { PermString s; int ax = 0; Vector types; if (naxes() < 1) return; if (!_l.is("[") || !_mmspace) goto error; _mmspace->check(); while (_l.is("/%/s", &s)) _mmspace->set_axis_type(ax++, s); if (!_l.is("]")) goto error; return; error: lerror("bad BlendAxisTypes"); } void AmfmReader::read_axis(int ax) const { bool ok = _mmspace && ax < naxes(); if (!ok) lerror("bad axis number %d", ax); else _mmspace->check(); PermString s; while (_l.next_line()) switch (_l[0]) { case 'A': if (_l.is("AxisType %+s", &s)) { if (ok) _mmspace->set_axis_type(ax, s); break; } if (_l.is("AxisLabel %+s", &s)) { if (ok) _mmspace->set_axis_label(ax, s); break; } goto invalid; case 'C': if (_l.is("Comment")) break; goto invalid; case 'E': if (_l.isall("EndAxis")) goto endaxis; goto invalid; default: invalid: no_match_warning(); } endaxis: ; } void AmfmReader::read_master(int m) const { AmfmMaster *amfmm; AmfmMaster dummy; if (m >= nmasters()) { lerror("too many masters"); amfmm = &dummy; } else { if (!_amfm->_masters) _amfm->_masters = new AmfmMaster[ nmasters() ]; amfmm = &_amfm->_masters[m]; } while (_l.next_line()) // Grok the whole line. Are we on a character metric data line? switch (_l[0]) { case 'C': if (_l.is("Comment")) break; goto invalid; case 'E': if (_l.isall("EndMaster")) goto endmaster; goto invalid; case 'F': if (_l.isall("FontName %+s", &amfmm->font_name)) break; if (_l.isall("FullName %+s", &amfmm->full_name)) break; if (_l.isall("FamilyName %+s", &amfmm->family)) break; goto invalid; case 'V': if (_l.isall("Version %+s", &amfmm->version)) break; goto invalid; case 'W': if (_l.is("WeightVector")) { if (!(read_simple_array(amfmm->weight_vector) && amfmm->weight_vector.size() == nmasters())) { lerror("bad WeightVector"); amfmm->weight_vector.clear(); } break; } goto invalid; default: invalid: no_match_warning(); } endmaster: ; } void AmfmReader::read_one_primary_font() const { AmfmPrimaryFont *pf = new AmfmPrimaryFont; pf->design_vector.resize(naxes()); pf->labels.resize(naxes()); while (_l.left()) { if (_l.is("PC")) { for (int a = 0; a < naxes(); a++) if (!_l.is("%d", &pf->design_vector[a])) goto error; } else if (_l.is("PL")) { for (int a = 0; a < naxes(); a++) if (!_l.is("(-%/s-)", &pf->labels[a])) goto error; } else if (_l.is("PN %(", &pf->name)) ; else no_match_warning("primary font"); _l.is(";"); // get rid of any possible semicolon } pf->next = _amfm->_primary_fonts; _amfm->_primary_fonts = pf; return; error: delete pf; } void AmfmReader::read_primary_fonts() const { while (_l.next_line()) switch (_l[0]) { case 'C': if (_l.is("Comment")) break; goto invalid; case 'E': if (_l.isall("EndPrimaryFonts")) goto end_primary_fonts; goto invalid; case 'P': if (_l[1] == 'C' && isspace(_l[2])) { read_one_primary_font(); break; } goto invalid; default: invalid: no_match_warning(); } end_primary_fonts: ; } void AmfmReader::read_conversion_programs() const { String ndv, cdv, s; while (_l.next_line()) switch (_l[0]) { case 'C': if (_l.isall("CDV %<", &s)) { cdv += s; break; } goto invalid; case 'E': if (_l.isall("EndConversionPrograms")) goto end_conversion_programs; goto invalid; case 'N': if (_l.isall("NDV %<", &s)) { ndv += s; break; } goto invalid; default: invalid: no_match_warning(); break; } end_conversion_programs: if (_mmspace) { _mmspace->set_ndv(Type1Charstring(ndv)); _mmspace->set_cdv(Type1Charstring(cdv)); } } } lcdf-typetools-2.108/libefont/t1unparser.cc0000644000175000017500000000601613423375327015646 00000000000000// -*- related-file-name: "../include/efont/t1unparser.hh" -*- /* t1unparser.{cc,hh} -- debug printing of Type 1 fonts * * Copyright (c) 1998-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include namespace Efont { CharstringUnparser::CharstringUnparser() : CharstringInterp(), _one_command_per_line(false), _start_of_line(true) { } CharstringUnparser::CharstringUnparser(const CharstringUnparser &o) : CharstringInterp(o), _one_command_per_line(o._one_command_per_line), _start_of_line(o._start_of_line) { } void CharstringUnparser::clear() { _sa.clear(); _start_of_line = true; } bool CharstringUnparser::number(double n) { if (_start_of_line) { _sa << _indent; _start_of_line = false; } else _sa << ' '; _sa << n; return true; } bool CharstringUnparser::type1_command(int cmd) { if (_start_of_line) { _sa << _indent; _start_of_line = false; } else _sa << ' '; if (cmd >= 0 && cmd <= Cs::cLastCommand) _sa << Cs::command_names[cmd]; else _sa << "UNKNOWN_12_" << (cmd - 32); if (_one_command_per_line) { _sa << '\n'; _start_of_line = true; } return true; } bool CharstringUnparser::type2_command(int cmd, const unsigned char *data, int *left) { if (_start_of_line) { _sa << _indent; _start_of_line = false; } else _sa << ' '; if (cmd >= 0 && cmd <= Cs::cLastCommand) _sa << Cs::command_names[cmd]; else _sa << "UNKNOWN_12_" << (cmd - 32); switch (cmd) { case Cs::cHstem: case Cs::cHstemhm: case Cs::cVstem: case Cs::cVstemhm: case Cs::cHintmask: case Cs::cCntrmask: CharstringInterp::type2_command(cmd, data, left); break; } if (_one_command_per_line) { _sa << '\n'; _start_of_line = true; } return true; } void CharstringUnparser::act_hintmask(int, const unsigned char *data, int nhints) { _sa << '['; for (int i = 0; i < nhints; i++, data++) sprintf(_sa.extend(2), "%02X", *data); _sa << ']'; } String CharstringUnparser::value() { _start_of_line = true; return _sa.take_string(); } String CharstringUnparser::unparse(const Charstring *cs) { if (cs) { CharstringUnparser u; u.interpret(0, cs); return u.value(); } else return "(null)"; } String CharstringUnparser::unparse(const Charstring &cs) { CharstringUnparser u; u.interpret(0, &cs); return u.value(); } } lcdf-typetools-2.108/libefont/psres.cc0000644000175000017500000002512613423375327014701 00000000000000// -*- related-file-name: "../include/efont/psres.hh" -*- /* psres.{cc,hh} -- PSres.upr files * * Copyright (c) 1999-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include /* Get the correct functions for directory searching */ #if HAVE_DIRENT_H # include # define DIR_NAMLEN(dirent) strlen((dirent)->d_name) #else # define dirent direct # define DIR_NAMLEN(dirent) (dirent)->d_namlen # if HAVE_SYS_NDIR_H # include # endif # if HAVE_SYS_DIR_H # include # endif # if HAVE_NDIR_H # include # endif #endif #include namespace Efont { PsresDatabase::PsresDatabase() : _section_map(0) { _sections.push_back((PsresDatabaseSection *)0); } PsresDatabase::~PsresDatabase() { for (int i = 1; i < _sections.size(); i++) delete _sections[i]; } PsresDatabaseSection::PsresDatabaseSection(PermString section_name) : _section_name(section_name), _map(0) { _directories.push_back(PermString()); _values.push_back(String()); _value_escaped.push_back(true); } /* read_ps_line - gathers a line in `slurper', returns true if it is a normal line, false on end of file or a separator line (starts with `.'). Handles continuation lines but not backslash escaping. Stores location of first non-backslashed equals sign in `*equals_pos', or -1 if none. */ static bool read_psres_line(Slurper &slurper, int *equals_pos) { if (equals_pos) *equals_pos = -1; char *s = slurper.next_line(); if (!s) return false; bool is_terminator = s[0] == '.'; unsigned len, pos = 0, last_escape = ~0; bool found_eq = false; while (true) { len = slurper.cur_line_length(); if (len == 0) break; // process backslash escapes for (; pos < len - 1; pos++) { if (s[pos] == '\\') { // quote the next character pos++; last_escape = pos; } else if (!found_eq && s[pos] == '=') { // an equals sign: store its position if (equals_pos) *equals_pos = pos; found_eq = true; } else if (s[pos] == '%') { // unescaped '%' is a comment; return immediately after shortening line len = pos; goto done; } } // stop processing if not a continuation line if (pos == len || s[pos] != '\\') break; slurper.shorten_line(pos); s = slurper.append_next_line(); } if (pos < len && !found_eq && s[pos] == '=' && equals_pos) *equals_pos = pos; done: // eat trailing whitespace, except for the space in `\ ' if it ends the line // -- unless the `\' is the second `\' in a `\\'! for (pos = len; pos > 0 && (s[pos-1] == ' ' || s[pos-1] == '\t'); pos--) /* nada */; if (pos == last_escape) pos++; slurper.shorten_line(pos); return !is_terminator; } /* psres_escape: backslash escaping */ static unsigned psres_escape(char *s, unsigned len) { unsigned pos = 0, delta = 0; while (pos < len) { if (s[pos] == '\\') pos++, delta++; if (delta) s[pos-delta] = s[pos]; pos++; } s[pos-delta] = 0; return len-delta; } void PsresDatabaseSection::add_psres_file_section (Slurper &slurper, PermString directory, bool override) { int equals_pos; bool first_line = true; while (read_psres_line(slurper, &equals_pos)) { char *s = slurper.cur_line(); // check for a directory line if (first_line) { first_line = false; if (s[0] == '/') { psres_escape(s + 1, slurper.cur_line_length() - 1); directory = PermString(s + 1); continue; } } if (equals_pos < 0) { // report error? continue; } // get the key unsigned len = psres_escape(s, equals_pos); PermString key = PermString(s, len); int index = _map[key]; if (!override && index > 0) continue; // double equals means absolute pathname if (s[equals_pos + 1] == '=') equals_pos++; // get the value. Don't escape it yet len = slurper.cur_line_length() - (equals_pos + 1); String value = String(s + equals_pos + 1, len); // stick key and value into our data structure if (index == 0) { index = _directories.size(); _directories.push_back(directory); _values.push_back(value); _value_escaped.push_back(false); _map.insert(key, index); } else { _directories[index] = directory; _values[index] = value; _value_escaped[index] = false; } } } PsresDatabaseSection * PsresDatabase::force_section(PermString name) { if (_section_map[name] > 0) return _sections[_section_map[name]]; else { PsresDatabaseSection *s = new PsresDatabaseSection(name); int index = _sections.size(); _sections.push_back(s); _section_map.insert(name, index); return s; } } bool PsresDatabase::add_one_psres_file(Slurper &slurper, bool override) { if (!read_psres_line(slurper, 0)) return /* error */ false; char *s = slurper.cur_line(); unsigned len = slurper.cur_line_length(); if (len < 12 || memcmp(s, "PS-Resources", 12) != 0) return /* error */ false; bool exclusive = (len >= 22 && memcmp(s+12, "-Exclusive", 10) == 0); // skip list of sections while (read_psres_line(slurper, 0)) /* nada */; // now, read each section PermString directory = slurper.filename().directory(); while (read_psres_line(slurper, 0)) { s = slurper.cur_line(); len = psres_escape(s, slurper.cur_line_length()); PsresDatabaseSection *section = force_section(PermString(s, len)); section->add_psres_file_section(slurper, directory, override); } return exclusive; } bool PsresDatabase::add_psres_file(Filename &filename, bool override) { Slurper slurpy(filename); return add_one_psres_file(slurpy, override); } #ifndef WIN32 void PsresDatabase::add_psres_directory(PermString directory) { DIR *dir = opendir(directory.c_str()); if (!dir) return; while (struct dirent *dirent = readdir(dir)) { int len = DIR_NAMLEN(dirent); if (len > 4 && dirent->d_name[0] != '.' && memcmp(dirent->d_name + len - 4, ".upr", 4) == 0 && (len != 9 || memcmp(dirent->d_name, "PSres.upr", 9) != 0)) { Filename fn(directory, PermString(dirent->d_name, len)); add_psres_file(fn, false); } } closedir(dir); } #else /* WIN32 */ void PsresDatabase::add_psres_directory(PermString directory) { WIN32_FIND_DATA find_file_data; HANDLE hnd; int proceed = TRUE; PermString search_str = permcat(directory, "/*.*"); hnd = FindFirstFile(search_str.c_str(), &find_file_data); if (hnd == INVALID_HANDLE_VALUE) { return; } while (proceed) { int len = strlen(find_file_data.cFileName); if (len > 4 && find_file_data.cFileName[0] != '.' && _strnicmp(find_file_data.cFileName + len - 4, ".upr", 4) == 0 && (len != 9 || _strnicmp(find_file_data.cFileName, "PSres.upr", 9) != 0)) { Filename fn(directory, PermString(find_file_data.cFileName, len)); add_psres_file(fn, false); } proceed = FindNextFile (hnd, &find_file_data); } FindClose(hnd); } #endif /* WIN32 */ void PsresDatabase::add_psres_path(const char *path, const char *default_path, bool override) { if (!path && !default_path) return; else if (!path) { path = default_path; default_path = 0; } if (override && _sections.size() > 1) { PsresDatabase new_db; new_db.add_psres_path(path, default_path, false); add_database(&new_db, true); return; } while (*path) { const char *epath = path; while (*epath && *epath != ':') epath++; PermString directory(path, epath - path); Filename filename(directory, "PSres.upr"); if (epath == path) { add_psres_path(default_path, 0, false); default_path = 0; // don't use default path twice } else if (!filename.readable() || !add_psres_file(filename, false)) add_psres_directory(directory); path = (*epath ? epath+1 : epath); } } void PsresDatabase::add_database(PsresDatabase *db, bool override) { for (int i = 1; i < db->_sections.size(); i++) { PermString section_name = db->_sections[i]->section_name(); PsresDatabaseSection *section = force_section(section_name); section->add_section(db->_sections[i], override); } } void PsresDatabaseSection::add_section(PsresDatabaseSection *s, bool override) { for (HashMap::const_iterator i = s->_map.begin(); i; i++) { int value = i.value(); if (_map[i.key()] <= 0) { int my_index = _directories.size(); _directories.push_back(s->_directories[value]); _values.push_back(s->_values[value]); _value_escaped.push_back(s->_value_escaped[value]); _map.insert(i.key(), my_index); } else if (override) { int my_index = _map[i.key()]; _directories[my_index] = s->_directories[value]; _values[my_index] = s->_values[value]; _value_escaped[my_index] = s->_value_escaped[value]; } } } const String & PsresDatabaseSection::value(int index) { if (_value_escaped[index]) return _values[index]; else { char *data = _values[index].mutable_data(); int len = psres_escape(data, _values[index].length()); _values[index] = _values[index].substring(0, len); _value_escaped[index] = true; return _values[index]; } } Filename PsresDatabaseSection::filename_value(PermString key) { int index = _map[key]; if (!index) return Filename(); else if (!_directories[index]) return Filename(value(index)); else return Filename(_directories[index], value(index)); } const String & PsresDatabase::value(PermString sec, PermString key) const { PsresDatabaseSection *s = section(sec); if (s) return s->value(key); else return String::make_empty(); } const String & PsresDatabase::unescaped_value(PermString sec, PermString key) const { PsresDatabaseSection *s = section(sec); if (s) return s->unescaped_value(key); else return String::make_empty(); } Filename PsresDatabase::filename_value(PermString sec, PermString key) const { PsresDatabaseSection *s = section(sec); if (s) return s->filename_value(key); else return Filename(); } } lcdf-typetools-2.108/libefont/afm.cc0000644000175000017500000003667413423375327014322 00000000000000// -*- related-file-name: "../include/efont/afm.hh" -*- /* afm.{cc,hh} -- Adobe Font Metrics files * * Copyright (c) 1998-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include /* for UNKDOUBLE */ #include #include #include namespace Efont { AfmReader::AfmReader(AfmParser &parser, Metrics *afm, AfmMetricsXt *afm_xt, ErrorHandler *errh) : _afm(afm), _afm_xt(afm_xt), _l(parser), _composite_warned(false), _metrics_sets_warned(false), _y_width_warned(0) { _errh = errh ? errh : ErrorHandler::silent_handler(); } Metrics * AfmReader::read(Slurper &slurp, ErrorHandler *errh) { AfmParser p(slurp); if (!p.ok()) return 0; Metrics *afm = new Metrics; AfmMetricsXt *afm_xt = new AfmMetricsXt; afm->add_xt(afm_xt); AfmReader reader(p, afm, afm_xt, errh); if (!reader.read()) { delete afm; return 0; } else return afm; } Metrics * AfmReader::read(const Filename &fn, ErrorHandler *errh) { Slurper slurpy(fn); return read(slurpy, errh); } void AfmReader::lwarning(const char *format, ...) const { va_list val; va_start(val, format); _errh->xmessage(_l.landmark(), ErrorHandler::e_warning, format, val); va_end(val); } void AfmReader::lerror(const char *format, ...) const { va_list val; va_start(val, format); _errh->xmessage(_l.landmark(), ErrorHandler::e_error, format, val); va_end(val); } GlyphIndex AfmReader::find_err(PermString name, const char *) const { GlyphIndex gi = _afm->find(name); if (gi < 0) lerror("character `%s' doesn't exist", name.c_str()); return gi; } void AfmReader::composite_warning() const { if (!_composite_warned) lwarning("composite fonts not supported"); _composite_warned = 1; } void AfmReader::metrics_sets_warning() const { if (!_metrics_sets_warned) lwarning("only metrics set 0 is supported"); _metrics_sets_warned = 1; } void AfmReader::y_width_warning() const { if (_y_width_warned < 40) { lwarning("character has a nonzero Y width"); _y_width_warned++; if (_y_width_warned == 40) lwarning("I won't warn you again."); } } void AfmReader::no_match_warning(const char *context) const { // keyword() will fail (and a warning won't get printed) only if the string // is all whitespace, which the spec allows PermString keyword = _l.keyword(); if (!keyword) return; if (_l.key_matched()) { lwarning(context ? "bad `%s' command in %s:" : "bad `%s' command:", keyword.c_str(), context); lwarning("field %d %s", _l.fail_field(), _l.message().c_str()); } else lwarning(context ? "unknown command `%s' in %s" : "unknown command `%s'", keyword.c_str(), context); _l.clear_message(); } bool AfmReader::read() { AfmParser &l = _l; assert(_afm && _afm_xt); // First, read all opening comments into an array so we can print them out // later. PermString comment; while (l.next_line()) { if (l.isall("Comment %+s", &comment)) _afm_xt->opening_comments.push_back(comment); else if (l.isall("StartFontMetrics %g", (double *)0)) ; else { l.save_line(); break; } } _afm->set_scale(1000); unsigned invalid_lines = 0; PermString s; bool isbasefont; int metrics_sets; int direction; while (l.next_line()) switch (l.first()) { case 'A': if (l.isall("Ascender %g", &fd( fdAscender ))) break; goto invalid; case 'C': if (l.isall("Characters %d", (int *)0)) break; if (l.isall("CapHeight %g", &fd( fdCapHeight ))) break; if (l.isall("CharacterSet %+s", (PermString *) 0)) break; if (l.isall("CharWidth %g %g", (double *)0, (double *)0)) break; if (l.isall("Comment %+s", (PermString *) 0)) break; goto invalid; case 'D': if (l.isall("Descender %g", &fd( fdDescender ))) break; goto invalid; case 'E': if (l.isall("EncodingScheme %+s", &_afm_xt->encoding_scheme)) break; if (l.isall("EndDirection")) break; if (l.isall("EndFontMetrics")) goto done; if (l.isall("EscChar %d", (int *)0)) { composite_warning(); break; } goto invalid; case 'F': if (l.isall("FontName %+s", &s)) { _afm->set_font_name(s); break; } if (l.isall("FullName %+s", &s)) { _afm->set_full_name(s); break; } if (l.isall("FamilyName %+s", &s)) { _afm->set_family(s); break; } if (l.isall("FontBBox %g %g %g %g", &fd( fdFontBBllx ), &fd( fdFontBBlly ), &fd( fdFontBBurx ), &fd( fdFontBBury ))) break; goto invalid; case 'I': if (l.isall("ItalicAngle %g", &fd( fdItalicAngle ))) break; if (l.isall("IsBaseFont %b", &isbasefont)) { if (isbasefont == 0) composite_warning(); break; } if (l.isall("IsFixedV %b", (bool *)0)) { metrics_sets_warning(); break; } if (l.isall("IsFixedPitch %b", (bool *)0)) break; goto invalid; case 'M': if (l.isall("MappingScheme %d", (int *)0)) { composite_warning(); break; } if (l.isall("MetricsSets %d", &metrics_sets)) { if (metrics_sets != 0) metrics_sets_warning(); break; } goto invalid; case 'N': if (l.isall("Notice %+s", &_afm_xt->notice)) break; goto invalid; case 'S': if (l.isall("StartDirection %d", &direction)) { if (direction != 0) metrics_sets_warning(); break; } if (l.isall("StartCharMetrics %d", (int *)0)) { read_char_metrics(); break; } if (l.isall("StartKernData")) { read_kerns(); break; } if (l.isall("StartComposites %d", (int *)0)) { read_composites(); break; } if (l.isall("StdHW %g", &fd( fdStdHW ))) break; if (l.isall("StdVW %g", &fd( fdStdVW ))) break; if (l.isall("StartFontMetrics %g", (double *)0)) break; goto invalid; case 'U': if (l.isall("UnderlinePosition %g", &fd( fdUnderlinePosition ))) break; if (l.isall("UnderlineThickness %g", &fd( fdUnderlineThickness ))) break; goto invalid; case 'V': if (l.isall("Version %+s", &s)) { _afm->set_version(s); break; } if (l.isall("VVector %g %g", (double *)0, (double *)0)) { metrics_sets_warning(); break; } goto invalid; case 'W': if (l.isall("Weight %+s", &s)) { _afm->set_weight(s); break; } goto invalid; case 'X': if (l.isall("XHeight %g", &fd( fdXHeight ))) break; goto invalid; default: invalid: invalid_lines++; no_match_warning(); } done: if (invalid_lines >= l.lineno() - 10) return false; else return true; } static Vector ligature_left; static Vector ligature_right; static Vector ligature_result; void AfmReader::read_char_metric_data() const { int c = -1; double wx = UNKDOUBLE; double bllx = UNKDOUBLE, blly = 0, burx = 0, bury = 0; PermString n; PermString ligright, ligresult; AfmParser &l = _l; l.is("C %d ; WX %g ; N %/s ; B %g %g %g %g ;", &c, &wx, &n, &bllx, &blly, &burx, &bury); while (l.left()) { switch (l.first()) { case 'B': if (l.is("B %g %g %g %g", &bllx, &blly, &burx, &bury)) break; goto invalid; case 'C': if (l.is("C %d", &c)) break; if (l.is("CH <%x>", &c)) break; goto invalid; case 'E': if (l.isall("EndCharMetrics")) return; goto invalid; case 'L': if (l.is("L %/s %/s", &ligright, &ligresult)) { if (!n) lerror("ligature given, but character has no name"); else { ligature_left.push_back(n); ligature_right.push_back(ligright); ligature_result.push_back(ligresult); } break; } goto invalid; case 'N': if (l.is("N %/s", &n)) break; goto invalid; case 'W': if (l.is("WX %g", &wx) || l.is("W0X %g", &wx)) break; if (l.is("W %g %g", &wx, (double *)0) || l.is("W0 %g %g", &wx, (double *)0) || l.is("W0Y %g", (double *)0)) { y_width_warning(); break; } if (l.is("W1X %g", (double *)0) || l.is("W1Y %g", (double *)0) || l.is("W1 %g %g", (double *)0, (double *)0)) { metrics_sets_warning(); break; } goto invalid; default: invalid: // always warn about unknown directives here! no_match_warning("character metrics"); l.skip_until(';'); break; } l.is(";"); // get rid of any possible semicolon } // create the character if (!n) lwarning("character without a name ignored"); else { if (_afm->find(n) != -1) lwarning("character %s defined twice", n.c_str()); GlyphIndex gi = _afm->add_glyph(n); _afm->wd(gi) = wx; _afm->lf(gi) = bllx; _afm->rt(gi) = burx; _afm->tp(gi) = bury; _afm->bt(gi) = blly; if (c != -1) _afm->set_code(gi, c); } } void AfmReader::read_char_metrics() const { assert(!ligature_left.size()); while (_l.next_line()) // Grok the whole line. Are we on a character metric data line? switch (_l.first()) { case 'C': if (isspace(_l[1]) || (_l[1] == 'H' && isspace(_l[2]))) { read_char_metric_data(); break; } if (_l.is("Comment")) break; goto invalid; case 'E': if (_l.isall("EndCharMetrics")) goto end_char_metrics; goto invalid; default: invalid: no_match_warning(); } end_char_metrics: for (int i = 0; i < ligature_left.size(); i++) { GlyphIndex leftgi = find_err(ligature_left[i], "ligature"); GlyphIndex rightgi = find_err(ligature_right[i], "ligature"); GlyphIndex resultgi = find_err(ligature_result[i], "ligature"); if (leftgi >= 0 && rightgi >= 0 && resultgi >= 0) if (_afm->add_lig(leftgi, rightgi, resultgi)) lwarning("duplicate ligature; first ignored"); } ligature_left.clear(); ligature_right.clear(); ligature_result.clear(); } void AfmReader::read_kerns() const { double kx; PermString left, right; GlyphIndex leftgi, rightgi; AfmParser &l = _l; // AFM files have reversed pair programs when read. _afm->pair_program()->set_reversed(true); while (l.next_line()) switch (l.first()) { case 'C': if (l.is("Comment")) break; goto invalid; case 'E': if (l.isall("EndKernPairs")) break; if (l.isall("EndKernData")) return; if (l.isall("EndTrackKern")) break; goto invalid; case 'K': if (l.isall("KPX %/s %/s %g", &left, &right, &kx)) { goto validkern; } if (l.isall("KP %/s %/s %g %g", &left, &right, &kx, (double *)0)) { y_width_warning(); goto validkern; } if (l.isall("KPY %/s %/s %g", &left, &right, (double *)0)) { y_width_warning(); break; } if (l.isall("KPH <%x> <%x> %g %g", (int *)0, (int *)0, (double *)0, (double *)0)) { lwarning("KPH not supported"); break; } goto invalid; validkern: leftgi = find_err(left, "kern"); rightgi = find_err(right, "kern"); if (leftgi >= 0 && rightgi >= 0) // A kern with 0 amount is NOT useless! // (Because of multiple masters.) if (_afm->add_kern(leftgi, rightgi, _afm->add_kv(kx))) lwarning("duplicate kern; first pair ignored"); break; case 'S': if (l.isall("StartKernPairs %d", (int *)0) || l.isall("StartKernPairs0 %d", (int *)0)) break; if (l.isall("StartKernPairs1 %d", (int *)0)) { metrics_sets_warning(); break; } if (l.isall("StartTrackKern %d", (int *)0)) break; goto invalid; case 'T': if (l.isall("TrackKern %g %g %g %g %g", (double *)0, (double *)0, (double *)0, (double *)0, (double *)0)) break; // FIXME: implement TrackKern goto invalid; default: invalid: no_match_warning(); break; } } void AfmReader::read_composites() const { while (_l.next_line()) switch (_l.first()) { case 'C': if (_l.is("Comment")) break; if (_l.is("CC")) break; goto invalid; case 'E': if (_l.isall("EndComposites")) return; goto invalid; default: invalid: no_match_warning(); break; } } } lcdf-typetools-2.108/libefont/findmet.cc0000644000175000017500000001713013423375327015167 00000000000000// -*- related-file-name: "../include/efont/findmet.hh" -*- /* findmet.{cc,hh} -- find font metrics * * Copyright (c) 1998-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include namespace Efont { MetricsFinder::~MetricsFinder() { if (_next) _next->_prev = _prev; if (_prev) _prev->_next = _next; } void MetricsFinder::add_finder(MetricsFinder *new_finder) { if (_next) _next->add_finder(new_finder); else { assert(!new_finder->_prev); new_finder->_prev = this; _next = new_finder; } } Metrics * MetricsFinder::find_metrics(PermString name, ErrorHandler *errh) { MetricsFinder *f = this; while (f) { Metrics *m = f->find_metrics_x(name, this, errh); if (m) return m; f = f->_next; } return 0; } AmfmMetrics * MetricsFinder::find_amfm(PermString name, ErrorHandler *errh) { MetricsFinder *f = this; while (f) { AmfmMetrics *m = f->find_amfm_x(name, this, errh); if (m) return m; f = f->_next; } return 0; } void MetricsFinder::record(Metrics *m) { record(m, m->font_name()); } void MetricsFinder::record(Metrics *m, PermString name) { if (_next) _next->record(m, name); } void MetricsFinder::record(AmfmMetrics *amfm) { if (_next) _next->record(amfm); } Metrics * MetricsFinder::find_metrics_x(PermString, MetricsFinder *, ErrorHandler *) { return 0; } AmfmMetrics * MetricsFinder::find_amfm_x(PermString, MetricsFinder *, ErrorHandler *) { return 0; } Metrics * MetricsFinder::try_metrics_file(const Filename &fn, MetricsFinder *finder, ErrorHandler *errh) { if (fn.readable()) { Metrics *afm = AfmReader::read(fn, errh); if (afm) finder->record(afm); return afm; } else return 0; } AmfmMetrics * MetricsFinder::try_amfm_file(const Filename &fn, MetricsFinder *finder, ErrorHandler *errh) { if (fn.readable()) { AmfmMetrics *amfm = AmfmReader::read(fn, finder, errh); if (amfm) finder->record(amfm); return amfm; } else return 0; } /***** * CacheMetricsFinder **/ CacheMetricsFinder::CacheMetricsFinder() : _metrics_map(-1), _amfm_map(-1) { } CacheMetricsFinder::~CacheMetricsFinder() { clear(); } Metrics * CacheMetricsFinder::find_metrics_x(PermString name, MetricsFinder *, ErrorHandler *) { int index = _metrics_map[name]; return index >= 0 ? _metrics[index] : 0; } AmfmMetrics * CacheMetricsFinder::find_amfm_x(PermString name, MetricsFinder *, ErrorHandler*) { int index = _amfm_map[name]; return index >= 0 ? _amfm[index] : 0; } void CacheMetricsFinder::record(Metrics *m, PermString name) { int index = _metrics.size(); _metrics.push_back(m); _metrics_map.insert(name, index); m->use(); MetricsFinder::record(m, name); } void CacheMetricsFinder::record(AmfmMetrics *amfm) { int index = _amfm.size(); _amfm.push_back(amfm); _amfm_map.insert(amfm->font_name(), index); amfm->use(); MetricsFinder::record(amfm); } void CacheMetricsFinder::clear() { for (int i = 0; i < _metrics.size(); i++) _metrics[i]->unuse(); for (int i = 0; i < _amfm.size(); i++) _amfm[i]->unuse(); _metrics.clear(); _amfm.clear(); _metrics_map.clear(); _amfm_map.clear(); } /***** * InstanceMetricsFinder **/ InstanceMetricsFinder::InstanceMetricsFinder(bool call_mmpfb) : _call_mmpfb(call_mmpfb) { } Metrics * InstanceMetricsFinder::find_metrics_instance(PermString name, MetricsFinder *finder, ErrorHandler *errh) { const char *underscore = strchr(name.c_str(), '_'); PermString amfm_name = PermString(name.c_str(), underscore - name.c_str()); AmfmMetrics *amfm = finder->find_amfm(amfm_name, errh); if (!amfm) return 0; MultipleMasterSpace *mmspace = amfm->mmspace(); if (!mmspace->check_intermediate() && _call_mmpfb) { char *buf = new char[amfm->font_name().length() + 30]; sprintf(buf, "mmpfb -q --amcp-info '%s'", amfm->font_name().c_str()); FILE *f = popen(buf, "r"); if (f) { Filename fake(""); Slurper slurpy(fake, f); AmfmReader::add_amcp_file(slurpy, amfm, errh); pclose(f); } delete[] buf; } Vector design = mmspace->default_design_vector(); int i = 0; while (underscore[0] == '_' && underscore[1]) { double x = strtod(underscore + 1, const_cast(&underscore)); mmspace->set_design(design, i, x, errh); i++; } Vector weight; if (!mmspace->design_to_weight(design, weight, errh)) return 0; Metrics *new_afm = amfm->interpolate(design, weight, errh); if (new_afm) { finder->record(new_afm); // What if the dimensions changed because the user specified out-of-range // dimens? We don't want to reinterpolate each time, so record the new // AFM under that name as well. if (new_afm->font_name() != name) finder->record(new_afm, name); } return new_afm; } Metrics * InstanceMetricsFinder::find_metrics_x(PermString name, MetricsFinder *finder, ErrorHandler *errh) { if (strchr(name.c_str(), '_')) return find_metrics_instance(name, finder, errh); else return 0; } /***** * PsresMetricsFinder **/ PsresMetricsFinder::PsresMetricsFinder(PsresDatabase *psres) : _psres(psres) { } Metrics * PsresMetricsFinder::find_metrics_x(PermString name, MetricsFinder *finder, ErrorHandler *errh) { return try_metrics_file (_psres->filename_value("FontAFM", name), finder, errh); } AmfmMetrics * PsresMetricsFinder::find_amfm_x(PermString name, MetricsFinder *finder, ErrorHandler *errh) { return try_amfm_file (_psres->filename_value("FontAMFM", name), finder, errh); } /***** * DirectoryMetricsFinder **/ DirectoryMetricsFinder::DirectoryMetricsFinder(PermString d) : _directory(d) { } Metrics * DirectoryMetricsFinder::find_metrics_x(PermString name, MetricsFinder *finder, ErrorHandler *errh) { Metrics *afm = try_metrics_file (Filename(_directory, permcat(name, ".afm")), finder, errh); if (!afm) afm = try_metrics_file (Filename(_directory, permcat(name, ".AFM")), finder, errh); return afm; } AmfmMetrics * DirectoryMetricsFinder::find_amfm_x(PermString name, MetricsFinder *finder, ErrorHandler *errh) { AmfmMetrics *amfm = try_amfm_file (Filename(_directory, permcat(name, ".amfm")), finder, errh); if (!amfm) amfm = try_amfm_file (Filename(_directory, permcat(name, ".AMFM")), finder, errh); return amfm; } } lcdf-typetools-2.108/libefont/t1bounds.cc0000644000175000017500000000756413423375327015312 00000000000000// -*- related-file-name: "../include/efont/t1bounds.hh" -*- /* t1bounds.{cc,hh} -- charstring bounding box finder * * Copyright (c) 1998-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include namespace Efont { CharstringBounds::CharstringBounds() : _lb(UNKDOUBLE, UNKDOUBLE), _rt(UNKDOUBLE, UNKDOUBLE), _last_xf_program(0) { } CharstringBounds::CharstringBounds(const Transform& nonfont_xf) : _lb(UNKDOUBLE, UNKDOUBLE), _rt(UNKDOUBLE, UNKDOUBLE), _nonfont_xf(nonfont_xf), _last_xf_program(0) { } CharstringBounds::CharstringBounds(const Transform &nonfont_xf, const Vector &weight) : CharstringInterp(weight), _lb(UNKDOUBLE, UNKDOUBLE), _rt(UNKDOUBLE, UNKDOUBLE), _nonfont_xf(nonfont_xf), _last_xf_program(0) { } void CharstringBounds::clear() { _lb = _rt = Point(UNKDOUBLE, UNKDOUBLE); _width = Point(0, 0); } void CharstringBounds::xf_mark(const Bezier &b) { Bezier b1, b2; b.halve(b1, b2); xf_mark(b1.point(3)); if (!xf_controls_inside(b1)) xf_mark(b1); if (!xf_controls_inside(b2)) xf_mark(b2); } void CharstringBounds::act_width(int, const Point &w) { _width = w * _xf; } void CharstringBounds::act_line(int, const Point &p0, const Point &p1) { mark(p0); mark(p1); } void CharstringBounds::act_curve(int, const Point &p0, const Point &p1, const Point &p2, const Point &p3) { Point q0 = p0 * _xf; Point q1 = p1 * _xf; Point q2 = p2 * _xf; Point q3 = p3 * _xf; xf_mark(q0); xf_mark(q3); if (!xf_inside(q1) || !xf_inside(q2)) { Bezier b(q0, q1, q2, q3); xf_mark(b); } } void CharstringBounds::set_xf(const CharstringProgram *program) { if (_last_xf_program != program) { _last_xf_program = program; double matrix[6]; program->font_matrix(matrix); Transform font_xf = Transform(matrix).scaled(program->units_per_em()); font_xf.check_null(0.001); _xf = _nonfont_xf * font_xf; } } bool CharstringBounds::char_bounds(const CharstringContext &g, bool shift) { set_xf(g.program); CharstringInterp::interpret(g); if (shift) { _xf.raw_translate(_width - _xf.translation()); _nonfont_xf.raw_translate(_width - _nonfont_xf.translation()); _width = Point(0, 0); } return error() >= 0; } void CharstringBounds::translate(double dx, double dy) { _xf.translate(dx, dy); _nonfont_xf.translate(dx, dy); } bool CharstringBounds::output(double bb[4], double& width, bool use_cur_width) const { if (!KNOWN(_lb.x)) bb[0] = bb[1] = bb[2] = bb[3] = 0; else { bb[0] = _lb.x; bb[1] = _lb.y; bb[2] = _rt.x; bb[3] = _rt.y; } if (use_cur_width) width = _width.x; else { Point p = Point(0, 0) * _xf; width = p.x; } return error() >= 0; } bool CharstringBounds::bounds(const Transform& transform, const CharstringContext& g, double bb[4], double& width) { CharstringBounds b(transform); b.char_bounds(g, false); return b.output(bb, width, true); } bool CharstringBounds::bounds(const CharstringContext &g, double bb[4], double& width) { CharstringBounds b; b.char_bounds(g, false); return b.output(bb, width, true); } } // namespace Efont lcdf-typetools-2.108/libefont/t1interp.cc0000644000175000017500000010506413423375327015313 00000000000000// -*- related-file-name: "../include/efont/t1interp.hh" -*- /* t1interp.{cc,hh} -- Type 1/2 charstring interpretation * * Copyright (c) 1998-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #ifdef WIN32 # define random() rand() #endif #define CHECK_STACK(numargs) do { if (size() < numargs) return error(errUnderflow, cmd); } while (0) #define CHECK_STATE() do { if (_state < S_IPATH) return error(errOrdering, cmd); } while (0) #define CHECK_PATH_START() do { _state = S_PATH; } while (0) #define CHECK_PATH_END() do { if (_state == S_PATH) { act_closepath(cmd); } _state = S_IPATH; } while (0) #ifndef static_assert # define static_assert(c, msg) switch ((int) (c)) case 0: case (c): #endif namespace Efont { static const char * const error_formats[] = { "charstring OK", // errOK "charstring internal error in '%C'", // errInternal "charstring commands past end", // errRunoff "charstring command '%C' unimplemented", // errUnimplemented "charstring stack overflow", // errOverflow "charstring stack underflow in '%C'", // errUnderflow "charstring bad vector operation in '%C'", // errVector "charstring bad value in '%C'", // errValue "charstring bad subroutine number %d", // errSubr "charstring bad glyph number '%d'", // errGlyph "charstring no current point in '%C'", // errCurrentPoint "charstring flex error", // errFlex "charstring multiple master error in '%C'", // errMultipleMaster "charstring open stroke", // errOpenStroke "charstring late sidebearing command '%C'", // errLateSidebearing "charstring bad othersubr number %d", // errOthersubr "charstring ordering constraints violated at '%C'", // errOrdering "charstring inappropriate hintmask", // errHintmask "charstring subrs nested too deep at '%d'" // errSubrDepth }; double CharstringInterp::double_for_error; CharstringInterp::CharstringInterp() : _error(errOK), _careful(false), _sp(0), _ps_sp(0), _scratch_vector(SCRATCH_SIZE, 0), _program(0) { } CharstringInterp::CharstringInterp(const Vector &weight_vector) : _error(errOK), _careful(false), _sp(0), _ps_sp(0), _weight_vector(weight_vector), _scratch_vector(SCRATCH_SIZE, 0), _program(0) { } void CharstringInterp::initialize() { clear(); ps_clear(); _lsb = _cp = _seac_origin = Point(0, 0); _state = S_INITIAL; _flex = false; _t2nhints = 0; _subr_depth = 0; _done = false; _error = errOK; } bool CharstringInterp::interpret(const CharstringProgram *program, const Charstring *cs) { if (cs) { initialize(); _program = program; cs->process(*this); return _error == errOK; } else return error(errGlyph, 0); } bool CharstringInterp::error(int err, int error_data) { _error = err; _error_data = error_data; return false; } String CharstringInterp::error_string(int error, int error_data) { static_assert(-errLastError == (sizeof(error_formats) / sizeof(error_formats[0])) - 1, "errLastError defined incorrectly"); if (error >= 0) return error_formats[0]; else if (error < errLastError) return "charstring unknown error number " + String(error); String format = error_formats[-error]; int percent = format.find_left('%'); if (percent >= 0 && format[percent + 1] == 'C') return format.substring(0, percent) + Charstring::command_name(error_data) + format.substring(percent + 2); else if (percent >= 0 && format[percent + 1] == 'd') return format.substring(0, percent) + String(error_data) + format.substring(percent + 2); else return format; } bool CharstringInterp::number(double v) { push(v); return true; } void CharstringInterp::fetch_weight_vector() { if (_program) if (Vector *wv = _program->mm_vector(CharstringProgram::VEC_WEIGHT, false)) _weight_vector = *wv; } bool CharstringInterp::vector_command(int cmd) { CharstringProgram::VectorType which_vector; int vectoroff, offset, num, i; Vector *v = 0; switch (cmd) { case Cs::cPut: CHECK_STACK(2); offset = (int)top(0); vec(&_scratch_vector, offset) = top(1); pop(2); break; case Cs::cGet: CHECK_STACK(1); offset = (int)top(); top() = vec(&_scratch_vector, offset); break; case Cs::cStore: CHECK_STACK(4); which_vector = (CharstringProgram::VectorType)((int)top(3)); vectoroff = (int)top(2); offset = (int)top(1); num = (int)top(0); pop(4); if (!_program) return error(errVector, cmd); v = _program->mm_vector(which_vector, true); if (!v) return error(errVector, cmd); for (i = 0; i < num; i++, offset++, vectoroff++) vec(v, vectoroff) = vec(&_scratch_vector, offset); // erase our weight vector if the global weight vector has changed if (which_vector == CharstringProgram::VEC_WEIGHT) _weight_vector.clear(); break; case Cs::cLoad: CHECK_STACK(3); which_vector = (CharstringProgram::VectorType)((int)top(2)); offset = (int)top(1); num = (int)top(0); pop(3); if (!_program) return error(errVector, cmd); v = _program->mm_vector(which_vector, false); // use our weight vector if appropriate if (!v && which_vector == CharstringProgram::VEC_WEIGHT && _weight_vector.size()) v = &_weight_vector; if (!v) return error(errVector, cmd); for (i = 0; i < num; i++, offset++) vec(&_scratch_vector, offset) = vec(v, i); break; default: return error(errUnimplemented, cmd); } return true; } bool CharstringInterp::blend_command() { const int cmd = Cs::cBlend; CHECK_STACK(1); int nargs = (int)pop(); ensure_weight_vector(); if (!_weight_vector.size()) return error(errVector, cmd); int nmasters = _weight_vector.size(); CHECK_STACK(nargs * nmasters); int base = _sp - nargs * nmasters; int off = base + nargs; for (int j = 0; j < nargs; j++) { double &val = _s[base + j]; for (int i = 1; i < nmasters; i++, off++) val += _weight_vector.at_u(i) * _s[off]; } pop(nargs * (nmasters - 1)); return true; } bool CharstringInterp::roll_command() { const int cmd = Cs::cRoll; CHECK_STACK(2); int amount = (int)pop(); int n = (int)pop(); if (n <= 0) return error(errValue, cmd); CHECK_STACK(n); int base = _sp - n; while (amount < 0) amount += n; int i; double copy_stack[STACK_SIZE]; for (i = 0; i < n; i++) copy_stack[i] = _s[ base + (i+amount) % n ]; for (i = 0; i < n; i++) _s[base + i] = copy_stack[i]; return true; } bool CharstringInterp::arith_command(int cmd) { int i; double d; switch (cmd) { case Cs::cBlend: return blend_command(); case Cs::cAbs: CHECK_STACK(1); if (top() < 0) top() = -top(); break; case Cs::cAdd: CHECK_STACK(1); d = pop(); top() += d; break; case Cs::cSub: CHECK_STACK(1); d = pop(); top() -= d; break; case Cs::cDiv: CHECK_STACK(2); d = pop(); top() /= d; break; case Cs::cNeg: CHECK_STACK(1); top() = -top(); break; case Cs::cRandom: { double d; do { d = random() / ((double)RAND_MAX); } while (d == 0); push(d); break; } case Cs::cMul: CHECK_STACK(2); d = pop(); top() *= d; break; case Cs::cSqrt: CHECK_STACK(1); if (top() < 0) return error(errValue, cmd); top() = sqrt(top()); break; case Cs::cDrop: CHECK_STACK(1); pop(); break; case Cs::cExch: CHECK_STACK(2); d = top(0); top(0) = top(1); top(1) = d; break; case Cs::cIndex: CHECK_STACK(1); i = (int)top(); if (i < 0) return error(errValue, cmd); CHECK_STACK(i + 2); top() = top(i+1); break; case Cs::cRoll: return roll_command(); case Cs::cDup: CHECK_STACK(1); push(top()); break; case Cs::cAnd: CHECK_STACK(2); d = pop(); top() = (top() != 0) && (d != 0); break; case Cs::cOr: CHECK_STACK(2); d = pop(); top() = (top() != 0) || (d != 0); break; case Cs::cNot: CHECK_STACK(1); top() = (top() == 0); break; case Cs::cEq: CHECK_STACK(2); d = pop(); top() = (top() == d); break; case Cs::cIfelse: CHECK_STACK(4); if (top(1) > top(0)) top(3) = top(2); pop(3); break; case Cs::cPop: if (ps_size() < 1) return error(errUnderflow, cmd); push(ps_pop()); break; case 15: // this command is found with no explanation in JansonText-Roman CHECK_STACK(2); pop(2); return true; default: return error(errUnimplemented, cmd); } return true; } bool CharstringInterp::callsubr_command() { const int cmd = Cs::cCallsubr; CHECK_STACK(1); int which = (int)pop(); Charstring *subr_cs = get_subr(which); if (!subr_cs) return error(errSubr, which); if (_subr_depth >= MAX_SUBR_DEPTH) return error(errSubrDepth, which); _subr_depth++; subr_cs->process(*this); _subr_depth--; if (_error != errOK) return false; return !done(); } bool CharstringInterp::callgsubr_command() { const int cmd = Cs::cCallgsubr; CHECK_STACK(1); int which = (int)pop(); Charstring *subr_cs = get_gsubr(which); if (!subr_cs) return error(errSubr, which); if (_subr_depth >= MAX_SUBR_DEPTH) return error(errSubrDepth, which); _subr_depth++; subr_cs->process(*this); _subr_depth--; if (_error != errOK) return false; return !done(); } bool CharstringInterp::mm_command(int command, int on_stack) { ensure_weight_vector(); if (!_weight_vector.size()) return error(errVector, command); int nargs; switch (command) { case Cs::othcMM1: nargs = 1; break; case Cs::othcMM2: nargs = 2; break; case Cs::othcMM3: nargs = 3; break; case Cs::othcMM4: nargs = 4; break; case Cs::othcMM6: nargs = 6; break; default: return error(errInternal, command); } int nmasters = _weight_vector.size(); if (size() < nargs * nmasters || on_stack != nargs * nmasters) return error(errMultipleMaster, command); int base = size() - on_stack; int off = base + nargs; for (int j = 0; j < nargs; j++) { double &val = at(base + j); for (int i = 1; i < nmasters; i++, off++) val += _weight_vector.at_u(i) * at(off); } for (int i = nargs - 1; i >= 0; i--) ps_push(at(base + i)); pop(on_stack); return true; } bool CharstringInterp::itc_command(int command, int on_stack) { ensure_weight_vector(); if (!_weight_vector.size()) return error(errVector, command); int base = size() - on_stack; switch (command) { case Cs::othcITC_load: { if (on_stack != 1) return error(errOthersubr, command); int offset = (int)at(base); for (int i = 0; i < _weight_vector.size(); i++) vec(&_scratch_vector, offset+i) = _weight_vector.at_u(i); break; } case Cs::othcITC_put: { if (on_stack != 2) return error(errOthersubr, command); int offset = (int)at(base+1); vec(&_scratch_vector, offset) = at(base); break; } case Cs::othcITC_get: { if (on_stack != 1) return error(errOthersubr, command); int offset = (int)at(base); ps_push(vec(&_scratch_vector, offset)); break; } case Cs::othcITC_add: { if (on_stack != 2) return error(errOthersubr, command); ps_push(at(base) + at(base+1)); break; } case Cs::othcITC_sub: { if (on_stack != 2) return error(errOthersubr, command); ps_push(at(base) - at(base+1)); break; } case Cs::othcITC_mul: { if (on_stack != 2) return error(errOthersubr, command); ps_push(at(base) * at(base+1)); break; } case Cs::othcITC_div: { if (on_stack != 2) return error(errOthersubr, command); ps_push(at(base) / at(base+1)); break; } case Cs::othcITC_ifelse: { if (on_stack != 4) return error(errOthersubr, command); if (at(base+2) <= at(base+3)) ps_push(at(base)); else ps_push(at(base+1)); break; } default: return error(errOthersubr, command); } pop(on_stack); return true; } inline void CharstringInterp::actp_rmoveto(int /*cmd*/, double dx, double dy) { _cp.shift(dx, dy); } inline void CharstringInterp::actp_rlineto(int cmd, double dx, double dy) { Point p0(_cp); _cp.shift(dx, dy); act_line(cmd, p0, _cp); } void CharstringInterp::actp_rrcurveto(int cmd, double dx1, double dy1, double dx2, double dy2, double dx3, double dy3) { Point p0(_cp); Point p1(p0, dx1, dy1); Point p2(p1, dx2, dy2); _cp = p2.shifted(dx3, dy3); act_curve(cmd, p0, p1, p2, _cp); } void CharstringInterp::actp_rrflex(int cmd, double dx1, double dy1, double dx2, double dy2, double dx3, double dy3, double dx4, double dy4, double dx5, double dy5, double dx6, double dy6, double flex_depth) { Point p0(_cp); Point p1(p0, dx1, dy1); Point p2(p1, dx2, dy2); Point p3_4(p2, dx3, dy3); Point p5(p3_4, dx4, dy4); Point p6(p5, dx5, dy5); _cp = p6.shifted(dx6, dy6); act_flex(cmd, p0, p1, p2, p3_4, p5, p6, _cp, flex_depth); } bool CharstringInterp::callothersubr_command(int othersubrnum, int n) { switch (othersubrnum) { case Cs::othcFlexend: if (n != 3) goto unknown; if (!_flex || ps_size() != 16) return error(errFlex); CHECK_PATH_START(); act_flex(Cs::cCallothersubr, Point(ps_at(0), ps_at(1)), Point(ps_at(4), ps_at(5)), Point(ps_at(6), ps_at(7)), Point(ps_at(8), ps_at(9)), Point(ps_at(10), ps_at(11)), Point(ps_at(12), ps_at(13)), Point(ps_at(14), ps_at(15)), top(2)); ps_clear(); ps_push(top(0)); ps_push(top(1)); _flex = false; _state = S_PATH; break; case Cs::othcFlexbegin: if (n != 0) goto unknown; if (_flex) return error(errFlex); ps_clear(); ps_push(_cp.x); ps_push(_cp.y); _flex = true; _state = S_IPATH; break; case Cs::othcFlexmiddle: if (n != 0) goto unknown; if (!_flex) return error(errFlex); ps_push(_cp.x); ps_push(_cp.y); break; case Cs::othcReplacehints: if (n != 1) goto unknown; ps_clear(); ps_push(top()); break; case Cs::othcMM1: case Cs::othcMM2: case Cs::othcMM3: case Cs::othcMM4: case Cs::othcMM6: return mm_command(othersubrnum, n); case Cs::othcITC_load: case Cs::othcITC_add: case Cs::othcITC_sub: case Cs::othcITC_mul: case Cs::othcITC_div: case Cs::othcITC_put: case Cs::othcITC_get: case Cs::othcITC_unknown: case Cs::othcITC_ifelse: case Cs::othcITC_random: return itc_command(othersubrnum, n); default: // unknown unknown: ps_clear(); for (int i = 0; i < n; i++) ps_push(top(i)); break; } pop(n); return true; } bool CharstringInterp::type1_command(int cmd) { switch (cmd) { case Cs::cReturn: return false; case Cs::cHsbw: CHECK_STACK(2); if (_state > S_SEAC && _careful) return error(errOrdering, cmd); else { _lsb = _cp = _seac_origin.shifted(at(0), 0); if (_state == S_INITIAL) { act_sidebearing(cmd, _lsb); act_width(cmd, Point(at(1), 0)); } if (_state <= S_SEAC) _state = S_SBW; } break; case Cs::cSbw: CHECK_STACK(4); if (_state > S_SEAC && _careful) return error(errOrdering, cmd); else { _lsb = _cp = _seac_origin.shifted(at(0), at(1)); if (_state == S_INITIAL) { act_sidebearing(cmd, _lsb); act_width(cmd, Point(at(2), at(3))); } if (_state <= S_SEAC) _state = S_SBW; } break; case Cs::cSeac: CHECK_STACK(5); if (_state > S_SBW) return error(errOrdering, cmd); act_seac(cmd, at(0), at(1), at(2), (int)at(3), (int)at(4)); clear(); return false; case Cs::cCallsubr: return callsubr_command(); case Cs::cCallothersubr: { CHECK_STACK(2); int othersubrnum = (int)top(0); int n = (int)top(1); pop(2); if (othersubrnum < 0 || size() < n) return error(errOthersubr, cmd); return callothersubr_command(othersubrnum, n); } case Cs::cPut: case Cs::cGet: case Cs::cStore: case Cs::cLoad: return vector_command(cmd); case Cs::cBlend: case Cs::cAbs: case Cs::cAdd: case Cs::cSub: case Cs::cDiv: case Cs::cNeg: case Cs::cRandom: case Cs::cMul: case Cs::cSqrt: case Cs::cDrop: case Cs::cExch: case Cs::cIndex: case Cs::cRoll: case Cs::cDup: case Cs::cAnd: case Cs::cOr: case Cs::cNot: case Cs::cEq: case Cs::cIfelse: case Cs::cPop: return arith_command(cmd); case Cs::cHlineto: CHECK_STACK(1); CHECK_PATH_START(); actp_rlineto(cmd, at(0), 0); break; case Cs::cHmoveto: CHECK_STACK(1); CHECK_PATH_END(); actp_rmoveto(cmd, at(0), 0); break; case Cs::cHvcurveto: CHECK_STACK(4); CHECK_PATH_START(); actp_rrcurveto(cmd, at(0), 0, at(1), at(2), 0, at(3)); break; case Cs::cRlineto: CHECK_STACK(2); CHECK_PATH_START(); actp_rlineto(cmd, at(0), at(1)); break; case Cs::cRmoveto: CHECK_STACK(2); CHECK_PATH_END(); actp_rmoveto(cmd, at(0), at(1)); break; case Cs::cRrcurveto: CHECK_STACK(6); CHECK_PATH_START(); actp_rrcurveto(cmd, at(0), at(1), at(2), at(3), at(4), at(5)); break; case Cs::cVhcurveto: CHECK_STACK(4); CHECK_PATH_START(); actp_rrcurveto(cmd, 0, at(0), at(1), at(2), at(3), 0); break; case Cs::cVlineto: CHECK_STACK(1); CHECK_PATH_START(); actp_rlineto(cmd, 0, at(0)); break; case Cs::cVmoveto: CHECK_STACK(1); CHECK_PATH_END(); actp_rmoveto(cmd, 0, at(0)); break; case Cs::cDotsection: break; case Cs::cHstem: CHECK_STACK(2); act_hstem(cmd, _lsb.y + at(0), at(1)); break; case Cs::cHstem3: CHECK_STACK(6); act_hstem3(cmd, _lsb.y + at(0), at(1), _lsb.y + at(2), at(3), _lsb.y + at(4), at(5)); break; case Cs::cVstem: CHECK_STACK(2); act_vstem(cmd, _lsb.x + at(0), at(1)); break; case Cs::cVstem3: CHECK_STACK(6); act_vstem3(cmd, _lsb.x + at(0), at(1), _lsb.x + at(2), at(3), _lsb.x + at(4), at(5)); break; case Cs::cSetcurrentpoint: CHECK_STACK(2); _cp = Point(at(0), at(1)); break; case Cs::cClosepath: CHECK_PATH_END(); break; case Cs::cEndchar: CHECK_PATH_END(); set_done(); return false; case Cs::cError: default: return error(errUnimplemented, cmd); } clear(); return error() >= 0; } #undef DEBUG_TYPE2 int CharstringInterp::type2_handle_width(int cmd, bool have_width) { _cp = _lsb = _seac_origin; if (_state != S_INITIAL) /* ignore width */; else if (have_width) act_nominal_width_delta(cmd, at(0)); else act_default_width(cmd); return (have_width ? 1 : 0); } bool CharstringInterp::type2_command(int cmd, const uint8_t *data, int *left) { int bottom = 0; #ifdef DEBUG_TYPE2 fprintf(stderr, "%s [%d/%d]\n", Charstring::command_name(cmd).c_str(), _t2nhints, size()); #endif switch (cmd) { case Cs::cHstem: case Cs::cHstemhm: CHECK_STACK(2); if (_state <= S_SEAC) bottom = type2_handle_width(cmd, (size() % 2) == 1); if (_state > S_HSTEM) return error(errOrdering, cmd); _state = S_HSTEM; for (double pos = 0; bottom + 1 < size(); bottom += 2) { _t2nhints++; act_hstem(cmd, pos + at(bottom), at(bottom + 1)); pos += at(bottom) + at(bottom + 1); } break; case Cs::cVstem: case Cs::cVstemhm: CHECK_STACK(2); if (_state <= S_SEAC) bottom = type2_handle_width(cmd, (size() % 2) == 1); if (_state > S_VSTEM) return error(errOrdering, cmd); _state = S_VSTEM; for (double pos = 0; bottom + 1 < size(); bottom += 2) { _t2nhints++; act_vstem(cmd, pos + at(bottom), at(bottom + 1)); pos += at(bottom) + at(bottom + 1); } break; case Cs::cHintmask: case Cs::cCntrmask: if (_state <= S_SEAC && size() >= 1) { bottom = type2_handle_width(cmd, (size() % 2) == 1); for (double pos = 0; bottom + 1 < size(); bottom += 2) { _t2nhints++; act_hstem(cmd, pos + at(bottom), at(bottom + 1)); pos += at(bottom) + at(bottom + 1); } } if ((_state == S_HSTEM || _state == S_VSTEM) && size() >= 2) for (double pos = 0; bottom + 1 < size(); bottom += 2) { _t2nhints++; act_vstem(cmd, pos + at(bottom), at(bottom + 1)); pos += at(bottom) + at(bottom + 1); } if (_state < S_HINTMASK) _state = S_HINTMASK; if (_t2nhints == 0) return error(errHintmask, cmd); if (!data || !left) return error(errInternal, cmd); if (((_t2nhints - 1) >> 3) + 1 > *left) return error(errRunoff, cmd); act_hintmask(cmd, data, _t2nhints); *left -= ((_t2nhints - 1) >> 3) + 1; break; case Cs::cRmoveto: CHECK_STACK(2); if (_state <= S_SEAC) bottom = type2_handle_width(cmd, size() > 2); CHECK_PATH_END(); actp_rmoveto(cmd, at(bottom), at(bottom + 1)); #if DEBUG_TYPE2 bottom += 2; #endif break; case Cs::cHmoveto: CHECK_STACK(1); if (_state <= S_SEAC) bottom = type2_handle_width(cmd, size() > 1); CHECK_PATH_END(); actp_rmoveto(cmd, at(bottom), 0); #if DEBUG_TYPE2 bottom++; #endif break; case Cs::cVmoveto: CHECK_STACK(1); if (_state <= S_SEAC) bottom = type2_handle_width(cmd, size() > 1); CHECK_PATH_END(); actp_rmoveto(cmd, 0, at(bottom)); #if DEBUG_TYPE2 bottom++; #endif break; case Cs::cRlineto: CHECK_STACK(2); CHECK_STATE(); CHECK_PATH_START(); for (; bottom + 1 < size(); bottom += 2) actp_rlineto(cmd, at(bottom), at(bottom + 1)); break; case Cs::cHlineto: CHECK_STACK(1); CHECK_STATE(); CHECK_PATH_START(); while (bottom < size()) { actp_rlineto(cmd, at(bottom++), 0); if (bottom < size()) actp_rlineto(cmd, 0, at(bottom++)); } break; case Cs::cVlineto: CHECK_STACK(1); CHECK_STATE(); CHECK_PATH_START(); while (bottom < size()) { actp_rlineto(cmd, 0, at(bottom++)); if (bottom < size()) actp_rlineto(cmd, at(bottom++), 0); } break; case Cs::cRrcurveto: CHECK_STACK(6); CHECK_STATE(); CHECK_PATH_START(); for (; bottom + 5 < size(); bottom += 6) actp_rrcurveto(cmd, at(bottom), at(bottom + 1), at(bottom + 2), at(bottom + 3), at(bottom + 4), at(bottom + 5)); break; case Cs::cHhcurveto: CHECK_STACK(4); CHECK_STATE(); CHECK_PATH_START(); if (size() % 2 == 1) { actp_rrcurveto(cmd, at(bottom + 1), at(bottom), at(bottom + 2), at(bottom + 3), at(bottom + 4), 0); bottom += 5; } for (; bottom + 3 < size(); bottom += 4) actp_rrcurveto(cmd, at(bottom), 0, at(bottom + 1), at(bottom + 2), at(bottom + 3), 0); break; case Cs::cHvcurveto: CHECK_STACK(4); CHECK_STATE(); CHECK_PATH_START(); while (bottom + 3 < size()) { double dx3 = (bottom + 5 == size() ? at(bottom + 4) : 0); actp_rrcurveto(cmd, at(bottom), 0, at(bottom + 1), at(bottom + 2), dx3, at(bottom + 3)); bottom += 4; if (bottom + 3 < size()) { double dy3 = (bottom + 5 == size() ? at(bottom + 4) : 0); actp_rrcurveto(cmd, 0, at(bottom), at(bottom + 1), at(bottom + 2), at(bottom + 3), dy3); bottom += 4; } } #if DEBUG_TYPE2 if (bottom + 1 == size()) bottom++; #endif break; case Cs::cRcurveline: CHECK_STACK(8); CHECK_STATE(); CHECK_PATH_START(); for (; bottom + 7 < size(); bottom += 6) actp_rrcurveto(cmd, at(bottom), at(bottom + 1), at(bottom + 2), at(bottom + 3), at(bottom + 4), at(bottom + 5)); actp_rlineto(cmd, at(bottom), at(bottom + 1)); #if DEBUG_TYPE2 bottom += 2; #endif break; case Cs::cRlinecurve: CHECK_STACK(8); CHECK_STATE(); CHECK_PATH_START(); for (; bottom + 7 < size(); bottom += 2) actp_rlineto(cmd, at(bottom), at(bottom + 1)); actp_rrcurveto(cmd, at(bottom), at(bottom + 1), at(bottom + 2), at(bottom + 3), at(bottom + 4), at(bottom + 5)); #if DEBUG_TYPE2 bottom += 6; #endif break; case Cs::cVhcurveto: CHECK_STACK(4); CHECK_STATE(); CHECK_PATH_START(); while (bottom + 3 < size()) { double dy3 = (bottom + 5 == size() ? at(bottom + 4) : 0); actp_rrcurveto(cmd, 0, at(bottom), at(bottom + 1), at(bottom + 2), at(bottom + 3), dy3); bottom += 4; if (bottom + 3 < size()) { double dx3 = (bottom + 5 == size() ? at(bottom + 4) : 0); actp_rrcurveto(cmd, at(bottom), 0, at(bottom + 1), at(bottom + 2), dx3, at(bottom + 3)); bottom += 4; } } #if DEBUG_TYPE2 if (bottom + 1 == size()) bottom++; #endif break; case Cs::cVvcurveto: CHECK_STACK(4); CHECK_STATE(); CHECK_PATH_START(); if (size() % 2 == 1) { actp_rrcurveto(cmd, at(bottom), at(bottom + 1), at(bottom + 2), at(bottom + 3), 0, at(bottom + 4)); bottom += 5; } for (; bottom + 3 < size(); bottom += 4) actp_rrcurveto(cmd, 0, at(bottom), at(bottom + 1), at(bottom + 2), 0, at(bottom + 3)); break; case Cs::cFlex: CHECK_STACK(13); CHECK_STATE(); CHECK_PATH_START(); assert(bottom == 0); actp_rrflex(cmd, at(0), at(1), at(2), at(3), at(4), at(5), at(6), at(7), at(8), at(9), at(10), at(11), at(12)); #if DEBUG_TYPE2 bottom += 13; #endif break; case Cs::cHflex: CHECK_STACK(7); CHECK_STATE(); CHECK_PATH_START(); assert(bottom == 0); actp_rrflex(cmd, at(0), 0, at(1), at(2), at(3), 0, at(4), 0, at(5), -at(2), at(6), 0, 50); #if DEBUG_TYPE2 bottom += 7; #endif break; case Cs::cHflex1: CHECK_STACK(9); CHECK_STATE(); CHECK_PATH_START(); assert(bottom == 0); actp_rrflex(cmd, at(0), at(1), at(2), at(3), at(4), 0, at(5), 0, at(6), at(7), at(8), -(at(1) + at(3) + at(7)), 50); #if DEBUG_TYPE2 bottom += 9; #endif break; case Cs::cFlex1: { CHECK_STACK(11); CHECK_STATE(); CHECK_PATH_START(); assert(bottom == 0); double dx = at(0) + at(2) + at(4) + at(6) + at(8); double dy = at(1) + at(3) + at(5) + at(7) + at(9); if (fabs(dx) > fabs(dy)) actp_rrflex(cmd, at(0), at(1), at(2), at(3), at(4), at(5), at(6), at(7), at(8), at(9), at(10), -dy, 50); else actp_rrflex(cmd, at(0), at(1), at(2), at(3), at(4), at(5), at(6), at(7), at(8), at(9), -dx, at(10), 50); break; #if DEBUG_TYPE2 bottom += 11; #endif } case Cs::cEndchar: if (_state <= S_SEAC) bottom = type2_handle_width(cmd, size() > 0 && size() != 4); if (bottom + 3 < size() && _state == S_INITIAL) act_seac(cmd, 0, at(bottom), at(bottom + 1), (int)at(bottom + 2), (int)at(bottom + 3)); CHECK_PATH_END(); set_done(); clear(); return false; case Cs::cReturn: return false; case Cs::cCallsubr: return callsubr_command(); case Cs::cCallgsubr: return callgsubr_command(); case Cs::cPut: case Cs::cGet: case Cs::cStore: case Cs::cLoad: return vector_command(cmd); case Cs::cBlend: case Cs::cAbs: case Cs::cAdd: case Cs::cSub: case Cs::cDiv: case Cs::cNeg: case Cs::cRandom: case Cs::cMul: case Cs::cSqrt: case Cs::cDrop: case Cs::cExch: case Cs::cIndex: case Cs::cRoll: case Cs::cDup: case Cs::cAnd: case Cs::cOr: case Cs::cNot: case Cs::cEq: case Cs::cIfelse: case Cs::cPop: return arith_command(cmd); case Cs::cDotsection: break; case Cs::cError: default: return error(errUnimplemented, cmd); } #if DEBUG_TYPE2 if (bottom != size()) fprintf(stderr, "[left %d on stack] ", size() - bottom); #endif clear(); return error() >= 0; } void CharstringInterp::act_sidebearing(int, const Point &) { /* do nothing */ } void CharstringInterp::act_width(int, const Point &) { /* do nothing */ } void CharstringInterp::act_default_width(int cmd) { double d = (_program ? _program->global_width_x(false) : UNKDOUBLE); if (KNOWN(d)) act_width(cmd, Point(d, 0)); } void CharstringInterp::act_nominal_width_delta(int cmd, double delta) { double d = (_program ? _program->global_width_x(true) : UNKDOUBLE); if (KNOWN(d)) act_width(cmd, Point(d + delta, 0)); } void CharstringInterp::act_seac(int cmd, double asb, double adx, double ady, int bchar, int achar) { Charstring *acs = 0, *bcs = 0; if (achar < 0 || achar >= 256 || bchar < 0 || bchar >= 256 || !_program || _program->parent_program() || !(acs = get_glyph(Charstring::standard_encoding[achar])) || !(bcs = get_glyph(Charstring::standard_encoding[bchar]))) { error(errGlyph, cmd); return; } Point apos = Point(adx + _lsb.x - asb, ady + _lsb.y); Point save_lsb = _lsb; Point save_seac_origin = _seac_origin; CharstringInterp::initialize(); _seac_origin = apos; _state = S_SEAC; acs->process(*this); if (error() == errOK) { CharstringInterp::initialize(); _seac_origin = save_seac_origin; _state = S_SEAC; bcs->process(*this); } _lsb = save_lsb; } void CharstringInterp::act_line(int cmd, const Point &p0, const Point &p1) { act_curve(cmd, p0, p0, p1, p1); } void CharstringInterp::act_curve(int cmd, const Point &, const Point &, const Point &, const Point &) { error(errUnimplemented, cmd); } void CharstringInterp::act_flex(int cmd, const Point &p0, const Point &p1, const Point &p2, const Point &p3_4, const Point &p5, const Point &p6, const Point &p7, double flex_depth) { (void) flex_depth; act_curve(cmd, p0, p1, p2, p3_4); act_curve(cmd, p3_4, p5, p6, p7); } void CharstringInterp::act_closepath(int) { /* do nothing */ } void CharstringInterp::act_hstem(int, double, double) { /* do nothing */ } void CharstringInterp::act_vstem(int, double, double) { /* do nothing */ } void CharstringInterp::act_hstem3(int cmd, double y0, double dy0, double y1, double dy1, double y2, double dy2) { act_hstem(cmd, y0, dy0); act_hstem(cmd, y1, dy1); act_hstem(cmd, y2, dy2); } void CharstringInterp::act_vstem3(int cmd, double x0, double dx0, double x1, double dx1, double x2, double dx2) { act_vstem(cmd, x0, dx0); act_vstem(cmd, x1, dx1); act_vstem(cmd, x2, dx2); } void CharstringInterp::act_hintmask(int, const uint8_t *, int) { /* do nothing */ } } lcdf-typetools-2.108/libefont/otfgpos.cc0000644000175000017500000002176713423375327015235 00000000000000// -*- related-file-name: "../include/efont/otfgpos.hh" -*- /* otfgpos.{cc,hh} -- OpenType GPOS table * * Copyright (c) 2003-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include namespace Efont { namespace OpenType { /************************** * Gpos * * * **************************/ Gpos::Gpos(const Data &d, ErrorHandler *errh) { // Fixed Version // Offset ScriptList // Offset FeatureList // Offset LookupList if (d.length() == 0) throw BlankTable("GPOS"); if (d.u16(0) != 1) throw Format("GPOS"); if (_script_list.assign(d.offset_subtable(4), errh) < 0) throw Format("GPOS script list"); if (_feature_list.assign(d.offset_subtable(6), errh) < 0) throw Format("GPOS feature list"); _lookup_list = d.offset_subtable(8); } int Gpos::nlookups() const { return _lookup_list.u16(0); } GposLookup Gpos::lookup(unsigned i) const { if (i >= _lookup_list.u16(0)) throw Error("GPOS lookup out of range"); else return GposLookup(_lookup_list.offset_subtable(2 + i*2)); } /************************** * GposValue * * * **************************/ const int GposValue::nibble_bitcount_x2[] = { 0, 2, 2, 4, 2, 4, 4, 6, 2, 4, 4, 6, 4, 6, 6, 8 }; /************************** * GposLookup * * * **************************/ GposLookup::GposLookup(const Data &d) : _d(d) { if (_d.length() < 6) throw Format("GPOS Lookup table"); _type = _d.u16(0); if (_type == L_EXTENSION && _d.u16(4) != 0) { Data first_subtable = _d.offset_subtable(HEADERSIZE); if (first_subtable.length() < 8 || first_subtable.u16(0) != 1) throw Format("GPOS Extension Lookup table"); _type = first_subtable.u16(2); } } Data GposLookup::subtable(int i) const { Data subd = _d.offset_subtable(HEADERSIZE + i*RECSIZE); if (_d.u16(0) != L_EXTENSION) return subd; else if (subd.length() >= 8 && subd.u16(0) == 1 && subd.u16(2) == _type) return subd.subtable(subd.u32(4)); else return Data(); } bool GposLookup::unparse_automatics(Vector &v, ErrorHandler *errh) const { int nlookup = _d.u16(4), success = 0; switch (_type) { case L_SINGLE: for (int i = 0; i < nlookup; i++) try { GposSingle s(subtable(i)); s.unparse(v); success++; } catch (Error e) { if (errh) errh->warning("%s, continuing", e.description.c_str()); } return success > 0; case L_PAIR: for (int i = 0; i < nlookup; i++) try { GposPair p(subtable(i)); p.unparse(v); success++; } catch (Error e) { if (errh) errh->warning("%s, continuing", e.description.c_str()); } return success > 0; default: return false; } } /************************** * GposSingle * * * **************************/ GposSingle::GposSingle(const Data &d) : _d(d) { if (_d[0] != 0 || (_d[1] != 1 && _d[1] != 2)) throw Format("GPOS Single Positioning"); Coverage coverage(_d.offset_subtable(2)); if (!coverage.ok() || (_d[1] == 2 && coverage.size() > _d.u16(6))) throw Format("GPOS Single Positioning coverage"); } Coverage GposSingle::coverage() const noexcept { return Coverage(_d.offset_subtable(2), 0, false); } void GposSingle::unparse(Vector &v) const { if (_d[1] == 1) { int format = _d.u16(4); Data value = _d.subtable(6); for (Coverage::iterator i = coverage().begin(); i; i++) v.push_back(Positioning(Position(*i, format, value))); } else { int format = _d.u16(4); int size = GposValue::size(format); for (Coverage::iterator i = coverage().begin(); i; i++) v.push_back(Positioning(Position(*i, format, _d.subtable(F2_HEADERSIZE + size*i.coverage_index())))); } } /************************** * GposPair * * * **************************/ GposPair::GposPair(const Data &d) : _d(d) { if (_d[0] != 0 || (_d[1] != 1 && _d[1] != 2)) throw Format("GPOS Pair Positioning"); Coverage coverage(_d.offset_subtable(2)); if (!coverage.ok() || (_d[1] == 1 && coverage.size() > _d.u16(8))) throw Format("GPOS Pair Positioning coverage"); } Coverage GposPair::coverage() const noexcept { return Coverage(_d.offset_subtable(2), 0, false); } void GposPair::unparse(Vector &v) const { if (_d[1] == 1) { int format1 = _d.u16(4); int format2 = _d.u16(6); int f2_pos = PAIRVALUE_HEADERSIZE + GposValue::size(format1); int pairvalue_size = f2_pos + GposValue::size(format2); for (Coverage::iterator i = coverage().begin(); i; i++) { Data pairset = _d.offset_subtable(F1_HEADERSIZE + i.coverage_index()*F1_RECSIZE); int npair = pairset.u16(0); for (int j = 0; j < npair; j++) { Data pair = pairset.subtable(PAIRSET_HEADERSIZE + j*pairvalue_size); v.push_back(Positioning(Position(*i, format1, pair.subtable(PAIRVALUE_HEADERSIZE)), Position(pair.u16(0), format2, pair.subtable(f2_pos)))); } } } else { // _d[1] == 2 int format1 = _d.u16(4); int format2 = _d.u16(6); int f2_pos = GposValue::size(format1); int recsize = f2_pos + GposValue::size(format2); ClassDef class1(_d.offset_subtable(8)); ClassDef class2(_d.offset_subtable(10)); Coverage coverage = this->coverage(); int nclass1 = _d.u16(12); int nclass2 = _d.u16(14); int offset = F2_HEADERSIZE; for (int c1 = 0; c1 < nclass1; c1++) for (int c2 = 0; c2 < nclass2; c2++, offset += recsize) { Position p1(format1, _d.subtable(offset)); Position p2(format2, _d.subtable(offset + f2_pos)); if (p1 || p2) { for (ClassDef::class_iterator c1i = class1.begin(c1, coverage); c1i; c1i++) for (ClassDef::class_iterator c2i = class2.begin(c2); c2i; c2i++) v.push_back(Positioning(Position(*c1i, p1), Position(*c2i, p2))); } } } } /************************** * Positioning * * * **************************/ static void unparse_glyphid(StringAccum &sa, Glyph gid, const Vector *gns) { if (!gns) gns = &debug_glyph_names; if (gid && gns && gns->size() > gid && (*gns)[gid]) sa << (*gns)[gid]; else sa << "g" << gid; } void Position::unparse(StringAccum &sa, const Vector *gns) const { unparse_glyphid(sa, g, gns); if (placed()) sa << '@' << pdx << ',' << pdy; sa << '+' << adx; if (ady) sa << '/' << ady; } String Position::unparse(const Vector *gns) const { StringAccum sa; unparse(sa, gns); return sa.take_string(); } bool Positioning::context_in(const Coverage &c) const { return (c.covers(_left.g) || !_left.g) && (!_right.g || c.covers(_right.g)); } bool Positioning::context_in(const GlyphSet &gs) const { return (gs.covers(_left.g) || !_left.g) && (!_right.g || gs.covers(_right.g)); } void Positioning::unparse(StringAccum &sa, const Vector *gns) const { if (!*this) sa << "NULL[]"; else if (is_single()) { sa << "SINGLE["; _left.unparse(sa, gns); sa << ']'; } else if (is_pairkern()) { sa << "KERN["; unparse_glyphid(sa, _left.g, gns); sa << ' '; unparse_glyphid(sa, _right.g, gns); sa << "+" << _left.adx << ']'; } else if (is_pair()) { sa << "PAIR["; _left.unparse(sa, gns); sa << ' '; _right.unparse(sa, gns); sa << ']'; } else sa << "UNKNOWN[]"; } String Positioning::unparse(const Vector *gns) const { StringAccum sa; unparse(sa, gns); return sa.take_string(); } }} #include lcdf-typetools-2.108/libefont/otfgsub.cc0000644000175000017500000011573013423375327015217 00000000000000// -*- related-file-name: "../include/efont/otfgsub.hh" -*- /* otfgsub.{cc,hh} -- OpenType GSUB table * * Copyright (c) 2003-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include namespace Efont { namespace OpenType { void Substitution::clear(Substitute &s, uint8_t &t) { switch (t) { case T_GLYPHS: delete[] s.gids; break; case T_COVERAGE: delete s.coverage; break; } t = T_NONE; } void Substitution::assign_space(Substitute &s, uint8_t &t, int n) { clear(s, t); if (n == 1) t = T_GLYPH; else if (n > 1) { s.gids = new Glyph[n + 1]; s.gids[0] = n; t = T_GLYPHS; } } void Substitution::assign(Substitute &s, uint8_t &t, Glyph gid) { clear(s, t); s.gid = gid; t = T_GLYPH; } void Substitution::assign(Substitute &s, uint8_t &t, int ngids, const Glyph *gids) { clear(s, t); assert(ngids > 0); if (ngids == 1) { s.gid = gids[0]; t = T_GLYPH; } else { s.gids = new Glyph[ngids + 1]; s.gids[0] = ngids; memcpy(s.gids + 1, gids, ngids * sizeof(Glyph)); t = T_GLYPHS; } } void Substitution::assign(Substitute &s, uint8_t &t, const Coverage &coverage) { clear(s, t); s.coverage = new Coverage(coverage); t = T_COVERAGE; } void Substitution::assign(Substitute &s, uint8_t &t, const Substitute &os, uint8_t ot) { if (&s == &os) return; switch (ot) { case T_NONE: clear(s, t); break; case T_GLYPH: assign(s, t, os.gid); break; case T_GLYPHS: assign(s, t, os.gids[0], os.gids + 1); break; case T_COVERAGE: assign(s, t, *os.coverage); break; default: assert(0); } } Substitution::Substitution(const Substitution &o) : _left_is(T_NONE), _in_is(T_NONE), _out_is(T_NONE), _right_is(T_NONE), _alternate(o._alternate) { assign(_left, _left_is, o._left, o._left_is); assign(_in, _in_is, o._in, o._in_is); assign(_out, _out_is, o._out, o._out_is); assign(_right, _right_is, o._right, o._right_is); } Substitution::Substitution(Glyph in, Glyph out) : _left_is(T_NONE), _in_is(T_GLYPH), _out_is(T_GLYPH), _right_is(T_NONE) { _in.gid = in; _out.gid = out; } Substitution::Substitution(Glyph in, const Vector &out, bool is_alternate) : _left_is(T_NONE), _in_is(T_GLYPH), _out_is(T_NONE), _right_is(T_NONE), _alternate(is_alternate) { assert(out.size() > 0); _in.gid = in; assign(_out, _out_is, out.size(), &out[0]); } Substitution::Substitution(Glyph in1, Glyph in2, Glyph out) : _left_is(T_NONE), _in_is(T_GLYPHS), _out_is(T_GLYPH), _right_is(T_NONE) { _in.gids = new Glyph[3]; _in.gids[0] = 2; _in.gids[1] = in1; _in.gids[2] = in2; _out.gid = out; } Substitution::Substitution(const Vector &in, Glyph out) : _left_is(T_NONE), _in_is(T_NONE), _out_is(T_GLYPH), _right_is(T_NONE) { assert(in.size() > 0); assign(_in, _in_is, in.size(), &in[0]); _out.gid = out; } Substitution::Substitution(int nin, const Glyph *in, Glyph out) : _left_is(T_NONE), _in_is(T_NONE), _out_is(T_GLYPH), _right_is(T_NONE) { assert(nin > 0); assign(_in, _in_is, nin, in); _out.gid = out; } Substitution::Substitution(int nleft, int nin, int nout, int nright) : _left_is(T_NONE), _in_is(T_NONE), _out_is(T_NONE), _right_is(T_NONE) { if (nleft) assign_space(_left, _left_is, nleft); if (nin) assign_space(_in, _in_is, nin); if (nout) assign_space(_out, _out_is, nout); if (nright) assign_space(_right, _right_is, nright); } Substitution::~Substitution() { clear(_left, _left_is); clear(_in, _in_is); clear(_out, _out_is); clear(_right, _right_is); } Substitution & Substitution::operator=(const Substitution &o) { assign(_left, _left_is, o._left, o._left_is); assign(_in, _in_is, o._in, o._in_is); assign(_out, _out_is, o._out, o._out_is); assign(_right, _right_is, o._right, o._right_is); _alternate = o._alternate; return *this; } bool Substitution::substitute_in(const Substitute &s, uint8_t t, const Coverage &c) { switch (t) { case T_NONE: return true; case T_GLYPH: return c.covers(s.gid); case T_GLYPHS: for (int i = 1; i <= s.gids[0]; i++) if (!c.covers(s.gids[i])) return false; return true; case T_COVERAGE: return *s.coverage <= c; default: assert(0); return false; } } bool Substitution::substitute_in(const Substitute &s, uint8_t t, const GlyphSet &gs) { switch (t) { case T_NONE: return true; case T_GLYPH: return gs.covers(s.gid); case T_GLYPHS: for (int i = 1; i <= s.gids[0]; i++) if (!gs.covers(s.gids[i])) return false; return true; case T_COVERAGE: for (Coverage::iterator i = s.coverage->begin(); i; i++) if (!gs.covers(*i)) return false; return true; default: assert(0); return false; } } bool Substitution::context_in(const Coverage &c) const { return substitute_in(_left, _left_is, c) && substitute_in(_in, _in_is, c) && substitute_in(_right, _right_is, c); } bool Substitution::context_in(const GlyphSet &gs) const { return substitute_in(_left, _left_is, gs) && substitute_in(_in, _in_is, gs) && substitute_in(_right, _right_is, gs); } Glyph Substitution::extract_glyph(const Substitute &s, uint8_t t) noexcept { return (t == T_GLYPH ? s.gid : 0); } Glyph Substitution::extract_glyph(const Substitute &s, int which, uint8_t t) noexcept { switch (t) { case T_GLYPH: return (which == 0 ? s.gid : 0); case T_GLYPHS: return (s.gids[0] > which ? s.gids[which + 1] : 0); case T_COVERAGE: for (Coverage::iterator ci = s.coverage->begin(); ci; ci++, which--) if (which == 0) return *ci; return 0; default: return 0; } } bool Substitution::extract_glyphs(const Substitute &s, uint8_t t, Vector &v, bool coverage_ok) noexcept { switch (t) { case T_GLYPH: v.push_back(s.gid); return true; case T_GLYPHS: for (int i = 1; i <= s.gids[0]; i++) v.push_back(s.gids[i]); return true; case T_COVERAGE: if (coverage_ok) { for (Coverage::iterator i = s.coverage->begin(); i; i++) v.push_back(*i); return true; } else return false; default: return false; } } Glyph * Substitution::extract_glyphptr(const Substitute &s, uint8_t t) noexcept { switch (t) { case T_GLYPH: return const_cast(&s.gid); case T_GLYPHS: return &s.gids[1]; default: return 0; } } int Substitution::extract_nglyphs(const Substitute &s, uint8_t t, bool coverage_ok) noexcept { switch (t) { case T_GLYPH: return 1; case T_GLYPHS: return s.gids[0]; case T_COVERAGE: return (coverage_ok ? 1 : 0); default: return 0; } } bool Substitution::matches(const Substitute &s, uint8_t t, int pos, Glyph g) noexcept { switch (t) { case T_GLYPH: return (pos == 0 && s.gid == g); case T_GLYPHS: return (pos >= 0 && pos < s.gids[0] && s.gids[1 + pos] == g); case T_COVERAGE: return (pos == 0 && s.coverage->covers(g)); default: return false; } } bool Substitution::is_noop() const { return (_in_is == T_GLYPH && _out_is == T_GLYPH && _in.gid == _out.gid) || (_in_is == T_GLYPHS && _out_is == T_GLYPHS && _in.gids[0] == _out.gids[0] && memcmp(_in.gids, _out.gids, (_in.gids[0] + 1) * sizeof(Glyph)) == 0); } bool Substitution::all_in_glyphs(Vector &gs) const { bool ok = true; gs.clear(); if (_left_is != T_NONE) ok &= extract_glyphs(_left, _left_is, gs, false); ok &= extract_glyphs(_in, _in_is, gs, false); if (_right_is != T_NONE) ok &= extract_glyphs(_right, _right_is, gs, false); return ok; } bool Substitution::all_out_glyphs(Vector &v) const { bool ok = true; if (_left_is != T_NONE) ok &= extract_glyphs(_left, _left_is, v, false); ok &= extract_glyphs(_out, _out_is, v, false); if (_right_is != T_NONE) ok &= extract_glyphs(_right, _right_is, v, false); return ok; } void Substitution::assign_append(Substitute &s, uint8_t &t, const Substitute &ls, uint8_t lt, const Substitute &rs, uint8_t rt) { if (lt == T_NONE) assign(s, t, rs, rt); else if (rt == T_NONE) assign(s, t, ls, lt); else if (lt != T_COVERAGE && rt != T_COVERAGE) { int nl = extract_nglyphs(ls, lt, false); int nr = extract_nglyphs(rs, rt, false); Glyph *gids = new Glyph[nl + nr + 1]; gids[0] = nl + nr; memcpy(&gids[1], extract_glyphptr(ls, lt), nl * sizeof(Glyph)); memcpy(&gids[1 + nl], extract_glyphptr(rs, rt), nr * sizeof(Glyph)); clear(s, t); s.gids = gids; t = T_GLYPHS; } else throw Error(); } void Substitution::assign_append(Substitute &s, uint8_t &t, const Substitute &ls, uint8_t lt, Glyph rg) { Substitute rs; rs.gid = rg; assign_append(s, t, ls, lt, rs, T_GLYPH); } Substitution Substitution::in_out_append_glyph(Glyph g) const { Substitution s; assign(s._left, s._left_is, _left, _left_is); assign(s._right, s._right_is, _right, _right_is); assign_append(s._in, s._in_is, _in, _in_is, g); assign_append(s._out, s._out_is, _out, _out_is, g); return s; } void Substitution::add_outer_left(Glyph g) { Substitute ls; ls.gid = g; assign_append(_left, _left_is, ls, T_GLYPH, _left, _left_is); } void Substitution::remove_outer_left() { if (_left_is == T_GLYPH) _left_is = T_NONE; else if (_left_is == T_GLYPHS) { if (_left.gids[0] == 2) assign(_left, _left_is, _left.gids[2]); else { _left.gids[0]--; memmove(_left.gids + 1, _left.gids + 2, _left.gids[0] * sizeof(Glyph)); } } } void Substitution::add_outer_right(Glyph g) { assign_append(_right, _right_is, _right, _right_is, g); } void Substitution::remove_outer_right() { if (_right_is == T_GLYPH) _right_is = T_NONE; else if (_right_is == T_GLYPHS) { if (_right.gids[0] == 2) assign(_right, _right_is, _right.gids[1]); else _right.gids[0]--; } } bool Substitution::out_alter(const Substitution &o, int pos) noexcept { const Glyph *g = out_glyphptr(); int ng = out_nglyphs(); const Glyph *out_g = o.out_glyphptr(); int out_ng = o.out_nglyphs(); int in_ng = o.in_nglyphs(); if (pos + in_ng > ng || out_ng == 0) return false; // check that input substitution actually matches us for (int i = 0; i < in_ng; i++) if (!o.in_matches(i, g[pos+i])) return false; // actually change output Vector new_g; for (int i = 0; i < pos; i++) new_g.push_back(g[i]); for (int i = 0; i < out_ng; i++) new_g.push_back(out_g[i]); for (int i = pos + in_ng; i < ng; i++) new_g.push_back(g[i]); assign(_out, _out_is, new_g.size(), &new_g[0]); return true; } static void unparse_glyphid(StringAccum &sa, Glyph gid, const Vector *gns) noexcept { if (gid > 0 && gns && gns->size() > gid && (*gns)[gid]) sa << (*gns)[gid]; else sa << "g" << gid; } void Substitution::unparse_glyphids(StringAccum &sa, const Substitute &s, uint8_t t, const Vector *gns) noexcept { if (t == T_GLYPH) unparse_glyphid(sa, s.gid, gns); else if (t == T_GLYPHS) { for (int i = 1; i <= s.gids[0]; i++) { if (i != 1) sa << ' '; unparse_glyphid(sa, s.gids[i], gns); } } else if (t == T_COVERAGE) sa << ""; else sa << "-"; } void Substitution::unparse(StringAccum &sa, const Vector *gns) const { if (!*this) sa << "NULL[]"; else { if (is_single()) sa << "SINGLE["; else if (is_ligature()) sa << "LIGATURE["; else if (is_multiple()) sa << "MULTIPLE["; else if (is_alternate()) sa << "ALTERNATE["; else if (is_simple_context()) sa << "SIMPLECONTEXT["; else sa << "UNKNOWN["; if (_left_is != T_NONE) { unparse_glyphids(sa, _left, _left_is, gns); sa << " | "; } unparse_glyphids(sa, _in, _in_is, gns); sa << " => "; unparse_glyphids(sa, _out, _out_is, gns); if (_right_is != T_NONE) { sa << " | "; unparse_glyphids(sa, _right, _right_is, gns); } sa << ']'; } } String Substitution::unparse(const Vector *gns) const { StringAccum sa; unparse(sa, gns); return sa.take_string(); } /************************** * Gsub * * * **************************/ Gsub::Gsub(const Data &d, const Font *otf, ErrorHandler *errh) : _chaincontext_reverse_backtrack(false) { // Fixed Version // Offset ScriptList // Offset FeatureList // Offset LookupList if (d.length() == 0) throw BlankTable("GSUB"); if (d.u16(0) != 1) throw Format("GSUB"); if (_script_list.assign(d.offset_subtable(4), errh) < 0) throw Format("GSUB script list"); if (_feature_list.assign(d.offset_subtable(6), errh) < 0) throw Format("GSUB feature list"); _lookup_list = d.offset_subtable(8); if (!otf) return; // Check for "correct" chaining context rules, as suggested by Adobe's // OpenType FDK try { Name nametable(otf->table("name"), ErrorHandler::silent_handler()); _chaincontext_reverse_backtrack = nametable.version_chaincontext_reverse_backtrack(); } catch (Error) { } } int Gsub::nlookups() const { return _lookup_list.u16(0); } GsubLookup Gsub::lookup(unsigned i) const { if (i >= _lookup_list.u16(0)) throw Error("GSUB lookup out of range"); else return GsubLookup(_lookup_list.offset_subtable(2 + i*2)); } /************************** * GsubLookup * * * **************************/ GsubLookup::GsubLookup(const Data &d) : _d(d) { if (_d.length() < 6) throw Format("GSUB Lookup table"); _type = _d.u16(0); if (_type == L_EXTENSION && _d.u16(4) != 0) { Data first_subtable = _d.offset_subtable(HEADERSIZE); if (first_subtable.length() < 8 || first_subtable.u16(0) != 1) throw Format("GSUB Extension Lookup table"); _type = first_subtable.u16(2); } } Data GsubLookup::subtable(int i) const { Data subd = _d.offset_subtable(HEADERSIZE + i*RECSIZE); if (_d.u16(0) != L_EXTENSION) return subd; else if (subd.length() >= 8 && subd.u16(0) == 1 && subd.u16(2) == _type) return subd.subtable(subd.u32(4)); else return Data(); } void GsubLookup::mark_out_glyphs(const Gsub &gsub, Vector &gmap) const { int nlookup = _d.u16(4); switch (_type) { case L_SINGLE: for (int i = 0; i < nlookup; i++) { GsubSingle x(subtable(i)); // this pattern makes gcc-3.3.4 happier x.mark_out_glyphs(gmap); } return; case L_MULTIPLE: for (int i = 0; i < nlookup; i++) { GsubMultiple x(subtable(i)); x.mark_out_glyphs(gmap); } return; case L_ALTERNATE: for (int i = 0; i < nlookup; i++) { GsubMultiple x(subtable(i)); x.mark_out_glyphs(gmap); } return; case L_LIGATURE: for (int i = 0; i < nlookup; i++) { GsubLigature x(subtable(i)); x.mark_out_glyphs(gmap); } return; case L_CONTEXT: for (int i = 0; i < nlookup; i++) { GsubContext x(subtable(i)); x.mark_out_glyphs(gsub, gmap); } return; case L_CHAIN: for (int i = 0; i < nlookup; i++) { GsubChainContext x(subtable(i)); x.mark_out_glyphs(gsub, gmap); } return; } } bool GsubLookup::unparse_automatics(const Gsub &gsub, Vector &v, const Coverage &limit) const { int nlookup = _d.u16(4); switch (_type) { case L_SINGLE: for (int i = 0; i < nlookup; i++) { GsubSingle x(subtable(i)); // this pattern makes gcc-3.3.4 happier x.unparse(v, limit); } return true; case L_MULTIPLE: for (int i = 0; i < nlookup; i++) { GsubMultiple x(subtable(i)); x.unparse(v); } return true; case L_ALTERNATE: for (int i = 0; i < nlookup; i++) { GsubMultiple x(subtable(i)); x.unparse(v, true); } return true; case L_LIGATURE: for (int i = 0; i < nlookup; i++) { GsubLigature x(subtable(i)); x.unparse(v); } return true; case L_CONTEXT: { bool understood = true; for (int i = 0; i < nlookup; i++) { GsubContext x(subtable(i)); understood &= x.unparse(gsub, v, limit); } return understood; } case L_CHAIN: { bool understood = true; for (int i = 0; i < nlookup; i++) { GsubChainContext x(subtable(i)); understood &= x.unparse(gsub, v, limit); } return understood; } default: return false; } } bool GsubLookup::apply(const Glyph *g, int pos, int n, Substitution &s) const { int nlookup = _d.u16(4); switch (_type) { case L_SINGLE: for (int i = 0; i < nlookup; i++) { GsubSingle x(subtable(i)); if (x.apply(g, pos, n, s)) return true; } return false; case L_MULTIPLE: for (int i = 0; i < nlookup; i++) { GsubMultiple x(subtable(i)); if (x.apply(g, pos, n, s)) return true; } return false; case L_ALTERNATE: for (int i = 0; i < nlookup; i++) { GsubMultiple x(subtable(i)); if (x.apply(g, pos, n, s, true)) return true; } return false; case L_LIGATURE: for (int i = 0; i < nlookup; i++) { GsubLigature x(subtable(i)); if (x.apply(g, pos, n, s)) return true; } return false; default: // XXX return false; } } /************************** * GsubSingle * * * **************************/ GsubSingle::GsubSingle(const Data &d) : _d(d) { if (_d[0] != 0 || (_d[1] != 1 && _d[1] != 2)) throw Format("GSUB Single Substitution"); Coverage coverage(_d.offset_subtable(2)); if (!coverage.ok() || (_d[1] == 2 && coverage.size() > _d.u16(4))) throw Format("GSUB Single Substitution coverage"); } Coverage GsubSingle::coverage() const noexcept { return Coverage(_d.offset_subtable(2), 0, false); } Glyph GsubSingle::map(Glyph g) const { int ci = coverage().coverage_index(g); if (ci < 0) return g; else if (_d[1] == 1) return g + _d.s16(4); else return _d.u16(HEADERSIZE + FORMAT2_RECSIZE*ci); } void GsubSingle::mark_out_glyphs(Vector &gmap) const { if (_d[1] == 1) { int delta = _d.s16(4); for (Coverage::iterator i = coverage().begin(); i; i++) gmap[*i + delta] = true; } else { for (Coverage::iterator i = coverage().begin(); i; i++) gmap[_d.u16(HEADERSIZE + i.coverage_index()*FORMAT2_RECSIZE)] = true; } } void GsubSingle::unparse(Vector &v, const Coverage &limit) const { if (_d[1] == 1) { int delta = _d.s16(4); for (Coverage::iterator it = coverage().begin(); it; ++it) if (limit.covers(*it)) v.push_back(Substitution(*it, *it + delta)); } else { for (Coverage::iterator it = coverage().begin(); it; ++it) if (limit.covers(*it)) v.push_back(Substitution(*it, _d.u16(HEADERSIZE + it.coverage_index()*FORMAT2_RECSIZE))); } } bool GsubSingle::apply(const Glyph *g, int pos, int n, Substitution &s) const { int ci; if (pos < n && (ci = coverage().coverage_index(g[pos])) >= 0) { if (_d[1] == 1) s = Substitution(g[pos], g[pos] + _d.s16(4)); else s = Substitution(g[pos], _d.u16(HEADERSIZE + ci*FORMAT2_RECSIZE)); return true; } else return false; } /************************** * GsubMultiple * * * **************************/ GsubMultiple::GsubMultiple(const Data &d) : _d(d) { if (_d[0] != 0 || _d[1] != 1) throw Format("GSUB Multiple Substitution"); Coverage coverage(_d.offset_subtable(2)); if (!coverage.ok() || coverage.size() > _d.u16(4)) throw Format("GSUB Multiple Substitution coverage"); } Coverage GsubMultiple::coverage() const noexcept { return Coverage(_d.offset_subtable(2), 0, false); } bool GsubMultiple::map(Glyph g, Vector &v) const { v.clear(); int ci = coverage().coverage_index(g); if (ci < 0) { v.push_back(g); return false; } else { Data seq = _d.offset_subtable(HEADERSIZE + ci*RECSIZE); for (int i = 0; i < seq.u16(0); i++) v.push_back(seq.u16(SEQ_HEADERSIZE + i*SEQ_RECSIZE)); return true; } } void GsubMultiple::mark_out_glyphs(Vector &gmap) const { for (Coverage::iterator i = coverage().begin(); i; ++i) { Data seq = _d.offset_subtable(HEADERSIZE + i.coverage_index()*RECSIZE); for (int j = 0; j < seq.u16(0); ++j) gmap[seq.u16(SEQ_HEADERSIZE + j*SEQ_RECSIZE)] = true; } } void GsubMultiple::unparse(Vector &v, bool is_alternate) const { Vector result; for (Coverage::iterator i = coverage().begin(); i; i++) { Data seq = _d.offset_subtable(HEADERSIZE + i.coverage_index()*RECSIZE); result.clear(); for (int j = 0; j < seq.u16(0); j++) result.push_back(seq.u16(SEQ_HEADERSIZE + j*SEQ_RECSIZE)); v.push_back(Substitution(*i, result, is_alternate)); } } bool GsubMultiple::apply(const Glyph *g, int pos, int n, Substitution &s, bool is_alternate) const { int ci; if (pos < n && (ci = coverage().coverage_index(g[pos])) >= 0) { Vector result; Data seq = _d.offset_subtable(HEADERSIZE + ci*RECSIZE); for (int j = 0; j < seq.u16(0); j++) result.push_back(seq.u16(SEQ_HEADERSIZE + j*SEQ_RECSIZE)); s = Substitution(g[pos], result, is_alternate); return true; } else return false; } /************************** * GsubLigature * * * **************************/ GsubLigature::GsubLigature(const Data &d) : _d(d) { if (_d[0] != 0 || _d[1] != 1) throw Format("GSUB Ligature Substitution"); Coverage coverage(_d.offset_subtable(2)); if (!coverage.ok() || coverage.size() > _d.u16(4)) throw Format("GSUB Ligature Substitution coverage"); } Coverage GsubLigature::coverage() const noexcept { return Coverage(_d.offset_subtable(2), 0, false); } bool GsubLigature::map(const Vector &gs, Glyph &result, int &consumed) const { assert(gs.size() > 0); result = gs[0]; consumed = 1; int ci = coverage().coverage_index(gs[0]); if (ci < 0) return false; Data ligset = _d.offset_subtable(HEADERSIZE + ci*RECSIZE); int nligset = ligset.u16(0); for (int i = 0; i < nligset; i++) { Data lig = ligset.offset_subtable(SET_HEADERSIZE + i*SET_RECSIZE); int nlig = lig.u16(2); if (nlig > gs.size() - 1) goto bad; for (int j = 0; j < nlig - 1; j++) if (lig.u16(LIG_HEADERSIZE + j*LIG_RECSIZE) != gs[j + 1]) goto bad; result = lig.u16(0); consumed = nlig + 1; return true; bad: ; } return false; } void GsubLigature::mark_out_glyphs(Vector &gmap) const { for (Coverage::iterator i = coverage().begin(); i; i++) { Data ligset = _d.offset_subtable(HEADERSIZE + i.coverage_index()*RECSIZE); int nligset = ligset.u16(0); Vector components(1, *i); for (int j = 0; j < nligset; j++) { Data lig = ligset.offset_subtable(SET_HEADERSIZE + j*SET_RECSIZE); gmap[lig.u16(0)] = true; } } } void GsubLigature::unparse(Vector &v) const { for (Coverage::iterator i = coverage().begin(); i; i++) { Data ligset = _d.offset_subtable(HEADERSIZE + i.coverage_index()*RECSIZE); int nligset = ligset.u16(0); Vector components(1, *i); for (int j = 0; j < nligset; j++) { Data lig = ligset.offset_subtable(SET_HEADERSIZE + j*SET_RECSIZE); int nlig = lig.u16(2); components.resize(1); for (int k = 0; k < nlig - 1; k++) components.push_back(lig.u16(LIG_HEADERSIZE + k*LIG_RECSIZE)); v.push_back(Substitution(components, lig.u16(0))); } } } bool GsubLigature::apply(const Glyph *g, int pos, int n, Substitution &s) const { int ci; if (pos < n && (ci = coverage().coverage_index(g[pos])) >= 0) { Data ligset = _d.offset_subtable(HEADERSIZE + ci*RECSIZE); int nligset = ligset.u16(0); for (int j = 0; j < nligset; j++) { Data lig = ligset.offset_subtable(SET_HEADERSIZE + j*SET_RECSIZE); int nlig = lig.u16(2); if (pos + nlig <= n) { for (int k = 0; k < nlig - 1; k++) if (lig.u16(LIG_HEADERSIZE + k*LIG_RECSIZE) != g[pos + k + 1]) goto ligature_failed; s = Substitution(nlig, &g[pos], lig.u16(0)); return true; } ligature_failed: ; } } return false; } /************************** * GsubContext * * * **************************/ GsubContext::GsubContext(const Data &d) : _d(d) { switch (_d.u16(0)) { case 1: case 2: break; case 3: { int ninput = _d.u16(2); if (ninput < 1) throw Format("GSUB Context Substitution input sequence"); Coverage coverage(_d.offset_subtable(F3_HSIZE)); if (!coverage.ok()) throw Format("GSUB Context Substitution coverage"); break; } default: throw Format("GSUB Context Substitution"); } } Coverage GsubContext::coverage() const noexcept { if (_d[1] == 3) return Coverage(_d.offset_subtable(F3_HSIZE), 0, false); else return Coverage(); } void GsubContext::subruleset_mark_out_glyphs(const Data &data, int nsub, int subtab_offset, const Gsub &gsub, Vector &gmap) { for (int j = 0; j < nsub; ++j) { int lookup_index = data.u16(subtab_offset + SUBRECSIZE*j + 2); gsub.lookup(lookup_index).mark_out_glyphs(gsub, gmap); } } void GsubContext::mark_out_glyphs(const Gsub &gsub, Vector &gmap) const { if (_d.u16(0) != 3) // XXX return; int nglyph = _d.u16(2); int nsubst = _d.u16(4); subruleset_mark_out_glyphs(_d, nsubst, F3_HSIZE + nglyph*2, gsub, gmap); } bool GsubContext::f1_unparse(const Data& data, int nsub, int subtab_offset, const Gsub& gsub, Vector& outsubs, Substitution s) { Substitution subtab_sub; int napplied = 0; for (int j = 0; j < nsub; j++) { int seq_index = data.u16(subtab_offset + SUBRECSIZE*j); int lookup_index = data.u16(subtab_offset + SUBRECSIZE*j + 2); // XXX check seq_index against size of output glyphs? if (gsub.lookup(lookup_index).apply(s.out_glyphptr(), seq_index, s.out_nglyphs(), subtab_sub)) { napplied++; s.out_alter(subtab_sub, seq_index); } } outsubs.push_back(s); return true; } bool GsubContext::f3_unparse(const Data &data, int nglyph, int glyphtab_offset, const Coverage &limit, int nsub, int subtab_offset, const Gsub &gsub, Vector &outsubs, const Substitution &prototype_sub) { Vector subs; subs.push_back(prototype_sub); Vector work_subs; // get array of possible substitutions including contexts for (int i = 0; i < nglyph; i++) { assert(!work_subs.size()); Coverage c(data.offset_subtable(glyphtab_offset + i*2)); for (Coverage::iterator ci = (c & limit).begin(); ci; ci++) for (int j = 0; j < subs.size(); j++) work_subs.push_back(subs[j].in_out_append_glyph(*ci)); subs.clear(); subs.swap(work_subs); } // now, apply referred lookups to the resulting substitution array Substitution subtab_sub; for (int i = 0; i < subs.size(); i++) { Substitution &s = subs[i]; int napplied = 0; for (int j = 0; j < nsub; j++) { int seq_index = data.u16(subtab_offset + SUBRECSIZE*j); int lookup_index = data.u16(subtab_offset + SUBRECSIZE*j + 2); // XXX check seq_index against size of output glyphs? if (gsub.lookup(lookup_index).apply(s.out_glyphptr(), seq_index, s.out_nglyphs(), subtab_sub)) { napplied++; s.out_alter(subtab_sub, seq_index); } } // 26.Jun.2003 -- always push substitution back, since the no-op might // override a following substitution outsubs.push_back(s); } return true; // XXX } bool GsubContext::unparse(const Gsub &gsub, Vector &v, const Coverage &limit) const { if (_d.u16(0) != 3) // XXX return false; int nglyph = _d.u16(2); int nsubst = _d.u16(4); return f3_unparse(_d, nglyph, F3_HSIZE, limit, nsubst, F3_HSIZE + nglyph*2, gsub, v, Substitution()); } /************************** * GsubChainContext * * * **************************/ GsubChainContext::GsubChainContext(const Data &d) : _d(d) { switch (_d.u16(0)) { case 1: { Coverage coverage(_d.offset_subtable(2)); if (!coverage.ok() || coverage.size() != _d.u16(4)) throw Format("ChainContext Substitution coverage"); break; } case 2: break; case 3: { int nbacktrack = _d.u16(2); int input_offset = F3_HSIZE + nbacktrack*2; int ninput = _d.u16(input_offset); if (ninput < 1) throw Format("GSUB ChainContext Substitution input sequence"); Coverage coverage(_d.offset_subtable(input_offset + F3_INPUT_HSIZE)); if (!coverage.ok()) throw Format("GSUB ChainContext Substitution coverage"); break; } default: throw Format("GSUB ChainContext Substitution"); } } Coverage GsubChainContext::coverage() const noexcept { switch (_d.u16(0)) { case 1: return Coverage(_d.offset_subtable(2), 0, false); case 3: { int nbacktrack = _d.u16(2); int input_offset = F3_HSIZE + nbacktrack*2; return Coverage(_d.offset_subtable(input_offset + F3_INPUT_HSIZE), 0, false); } default: return Coverage(); } } void GsubChainContext::mark_out_glyphs(const Gsub &gsub, Vector &gmap) const { switch (_d.u16(0)) { case 1: { int nsubruleset = _d.u16(4); for (int i = 0; i != nsubruleset; ++i) { int srs_offset = _d.u16(6 + i*2); int nsubrule = _d.u16(srs_offset); for (int j = 0; j != nsubrule; ++j) { int subrule_offset = srs_offset + _d.u16(srs_offset + 2 + j*2); int nbacktrack = _d.u16(subrule_offset); int input_offset = subrule_offset + 2 + nbacktrack*2; int ninput = _d.u16(input_offset); int lookahead_offset = input_offset + 2 + (ninput-1)*2; int nlookahead = _d.u16(lookahead_offset); int subst_offset = lookahead_offset + 2 + nlookahead*2; int nsubst = _d.u16(subst_offset); GsubContext::subruleset_mark_out_glyphs(_d, nsubst, subst_offset + 2, gsub, gmap); } } break; } case 3: { int nbacktrack = _d.u16(2); int input_offset = F3_HSIZE + nbacktrack*2; int ninput = _d.u16(input_offset); int lookahead_offset = input_offset + F3_INPUT_HSIZE + ninput*2; int nlookahead = _d.u16(lookahead_offset); int subst_offset = lookahead_offset + F3_LOOKAHEAD_HSIZE + nlookahead*2; int nsubst = _d.u16(subst_offset); GsubContext::subruleset_mark_out_glyphs(_d, nsubst, subst_offset + F3_SUBST_HSIZE, gsub, gmap); break; } default: return; } } bool GsubChainContext::f1_unparse(const Gsub &gsub, Vector &v, const Coverage &limit) const { Coverage input0_coverage(_d.offset_subtable(2), 0, false); Coverage::iterator i0iter = input0_coverage.begin(); for (int i0index = 0; i0index != input0_coverage.size(); ++i0index, ++i0iter) { int srs_offset = _d.u16(6 + i0index*2); int nsubrule = _d.u16(srs_offset); for (int srindex = 0; srindex != nsubrule; ++srindex) { int sr_offset = srs_offset + _d.u16(srs_offset + 2 + srindex*2); int nbacktrack = _d.u16(sr_offset); int input_offset = sr_offset + 2 + nbacktrack*2; int ninput = _d.u16(input_offset); int lookahead_offset = input_offset + 2 + (ninput-1)*2; int nlookahead = _d.u16(lookahead_offset); int subst_offset = lookahead_offset + 2 + nlookahead*2; int nsubst = _d.u16(subst_offset); int subtab_offset = subst_offset + 2; Substitution s(nbacktrack, ninput, ninput, nlookahead); if (gsub.chaincontext_reverse_backtrack()) { for (int i = 0; i != nbacktrack; ++i) s.left_glyphptr()[i] = _d.u16(sr_offset + 2 + i*2); } else { for (int i = nbacktrack - 1; i != -1; --i) s.left_glyphptr()[nbacktrack - 1 - i] = _d.u16(sr_offset + 2 + i*2); } Glyph* in_begin = s.in_glyphptr(); Glyph* out_begin = s.out_glyphptr(); in_begin[0] = out_begin[0] = *i0iter; for (int i = 1; i != ninput; ++i) in_begin[i] = out_begin[i] = _d.u16(input_offset + 2 + (i-1)*2); for (int i = 0; i != ninput; ++i) if (!limit.covers(in_begin[i])) goto skip; for (int i = 0; i != nlookahead; ++i) s.right_glyphptr()[i] = _d.u16(lookahead_offset + 2 + i*2); // now, apply referred lookups to the resulting substitution array GsubContext::f1_unparse(_d, nsubst, subtab_offset, gsub, v, s); skip: ; } } return true; } bool GsubChainContext::f3_unparse(const Gsub &gsub, Vector &v, const Coverage &limit) const { int nbacktrack = _d.u16(2); int input_offset = F3_HSIZE + nbacktrack*2; int ninput = _d.u16(input_offset); int lookahead_offset = input_offset + F3_INPUT_HSIZE + ninput*2; int nlookahead = _d.u16(lookahead_offset); int subst_offset = lookahead_offset + F3_LOOKAHEAD_HSIZE + nlookahead*2; int nsubst = _d.u16(subst_offset); Vector backtrackc; Vector lookaheadc; if (gsub.chaincontext_reverse_backtrack()) { for (int i = 0; i < nbacktrack; i++) backtrackc.push_back(Coverage(_d.offset_subtable(F3_HSIZE + i*2)) & limit); } else { for (int i = nbacktrack - 1; i >= 0; i--) backtrackc.push_back(Coverage(_d.offset_subtable(F3_HSIZE + i*2)) & limit); } for (int i = 0; i < nlookahead; i++) lookaheadc.push_back(Coverage(_d.offset_subtable(lookahead_offset + F3_LOOKAHEAD_HSIZE + i*2)) & limit); // give up if would generate too many substitutions double n = 1; for (int i = 0; i < nbacktrack; ++i) n *= backtrackc[i].size(); for (int i = 0; i < nlookahead; ++i) n *= lookaheadc[i].size(); for (int i = 0; i < ninput; ++i) n *= (Coverage(_d.offset_subtable(input_offset + F3_INPUT_HSIZE + i*2)) & limit).size(); if (n > 1000000) // arbitrary cutoff return false; Vector backtracki; Vector lookaheadi; for (int i = 0; i < nbacktrack; i++) backtracki.push_back(backtrackc[i].begin()); for (int i = 0; i < nlookahead; i++) lookaheadi.push_back(lookaheadc[i].begin()); bool any = false; while (1) { // run GsubContext Substitution s(nbacktrack, 0, 0, nlookahead); Glyph *left_begin = s.left_glyphptr(); for (int i = 0; i < nbacktrack; i++) left_begin[i] = *backtracki[i]; Glyph *right_begin = s.right_glyphptr(); for (int i = 0; i < nlookahead; i++) right_begin[i] = *lookaheadi[i]; any |= GsubContext::f3_unparse(_d, ninput, input_offset + F3_INPUT_HSIZE, limit, nsubst, subst_offset + F3_SUBST_HSIZE, gsub, v, s); // step iterators for (int i = nlookahead - 1; i >= 0; i--) { lookaheadi[i]++; if (lookaheadi[i]) goto next; lookaheadi[i] = lookaheadc[i].begin(); } for (int i = nbacktrack - 1; i >= 0; i--) { backtracki[i]++; if (backtracki[i]) goto next; backtracki[i] = backtrackc[i].begin(); } break; next: ; } return any; } bool GsubChainContext::unparse(const Gsub &gsub, Vector &v, const Coverage &limit) const { if (_d.u16(0) == 1) return f1_unparse(gsub, v, limit); else if (_d.u16(0) == 3) return f3_unparse(gsub, v, limit); else return false; } }} lcdf-typetools-2.108/libefont/t1rw.cc0000644000175000017500000003131513423375327014437 00000000000000// -*- related-file-name: "../include/efont/t1rw.hh" -*- /* t1rw.{cc,hh} -- Type 1 font reading and writing * * Copyright (c) 1998-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include namespace Efont { unsigned char Type1Reader::xvalue_store[257]; unsigned char *Type1Reader::xvalue = &Type1Reader::xvalue_store[1]; void Type1Reader::static_initialize() { if (xvalue['A']) return; // rely on static data being initialized to 0 xvalue['0'] = 0; xvalue['1'] = 1; xvalue['2'] = 2; xvalue['3'] = 3; xvalue['4'] = 4; xvalue['5'] = 5; xvalue['6'] = 6; xvalue['7'] = 7; xvalue['8'] = 8; xvalue['9'] = 9; xvalue['A'] = 10; xvalue['B'] = 11; xvalue['C'] = 12; xvalue['D'] = 13; xvalue['E'] = 14; xvalue['F'] = 15; xvalue['a'] = 10; xvalue['b'] = 11; xvalue['c'] = 12; xvalue['d'] = 13; xvalue['e'] = 14; xvalue['f'] = 15; } Type1Reader::Type1Reader() : _data(new unsigned char[DATA_SIZE]), _len(0), _pos(0), _ungot(-1), _eexec(false) { static_initialize(); } Type1Reader::~Type1Reader() { delete[] _data; } void Type1Reader::set_charstring_definer(PermString x) { _charstring_definer = x; } void Type1Reader::switch_eexec(bool on, unsigned char *data, int len) { if (on) { if (_pos < len + 3) { unsigned char *new_data = new unsigned char[len + 3 + DATA_SIZE]; assert(_len <= DATA_SIZE); memcpy(new_data + len + 3, _data + _pos, _len - _pos); _len = len + 3 + _len - _pos; _pos = len + 3; delete[] _data; _data = new_data; } int original_pos = _pos; // don't forget _ungot!! if (_ungot >= 0) _data[--_pos] = _ungot, _ungot = -1; if (_crlf == 0 || _crlf == 2) _data[--_pos] = '\n'; if (_crlf == 1 || _crlf == 2) _data[--_pos] = '\r'; memcpy(_data + _pos - len, data, len); _pos -= len; start_eexec(original_pos - _pos); } _eexec = on; } int Type1Reader::more_data() { _pos = 0; _len = more_data(_data, DATA_SIZE); if (_len < 0) return -1; else return _data[_pos++]; } inline int Type1Reader::get_base() { if (_pos >= _len) return more_data(); else return _data[_pos++]; } inline int Type1Reader::eexec(int c) { unsigned char answer = (unsigned char)(c ^ (_r >> 8)); _r = (((unsigned char)c + _r) * (uint32_t) t1C1 + t1C2) & 0xFFFF; return answer; } int Type1Reader::ascii_eexec_get() { int d1 = get_base(); while (isspace(d1)) d1 = get_base(); int d2 = get_base(); while (isspace(d2)) d2 = get_base(); if (d2 < 0) return -1; return eexec((xvalue[d1] << 4) | (xvalue[d2])); } inline int Type1Reader::get() { if (!_eexec) return get_base(); else if (_binary_eexec) { int c = get_base(); return c < 0 ? c : eexec(c); } else return ascii_eexec_get(); } void Type1Reader::start_eexec(int initial_ascii) { /* God damn this _ungot thing!! It makes sense not to check it on every char fetch, since it can only be set at the end of next_line; therefore, only the first get() into a user-visible function might need to check _ungot. The problem is I forgot start_eexec() was such a function! */ int c = _ungot < 0 ? get_base() : _ungot; initial_ascii--; _ungot = -1; /* Strictly speaking, I should look for whitespace even in binary sections of PFB fonts; but it turns out some PFBs would be unreadable with that pedantic rule. */ while (isspace(c) && (initial_ascii >= 0 || !preserve_whitespace())) c = get_base(), initial_ascii--; /* Differentiate between ASCII eexec and binary eexec. */ int rand_bytes[4]; _binary_eexec = false; for (int i = 0; i < 4; i++) { if (i) c = get_base(); rand_bytes[i] = c; if (!isxdigit(c)) _binary_eexec = true; } _r = t1R_ee; if (_binary_eexec) for (int i = 0; i < 4; i++) eexec(rand_bytes[i]); else { for (int i = 0; i < 2; i++) { c = xvalue[rand_bytes[i*2]] * 16 + xvalue[rand_bytes[i*2+1]]; eexec(c); } ascii_eexec_get(); ascii_eexec_get(); } } bool Type1Reader::test_charstring(StringAccum &str) { /* PERFORMANCE NOTE: This function is definitely a bottleneck. Making it more efficient cut time by about 40%. */ if (!_charstring_definer) return false; if (_charstring_len >= 0) return str.length() <= _charstring_start + _charstring_len; str.append('\0'); // protect against running off end of string char *s = str.data(); char *start; while (*s == ' ') s++; if (s[0] == '/') s++; else if (s[0] == 'd' && s[1] == 'u' && s[2] == 'p' && isspace((unsigned char) s[3])) { s += 4; // 17.Jan.2000 -- some fonts have extra space here. while (isspace((unsigned char) *s)) s++; } else goto not_charstring; // Force one literal space rather than isspace(). // Why? Consistency: we force 1 literal space around _charstring_definer. while (*s != ' ' && *s) s++; if (*s++ != ' ' || !isdigit((unsigned char) *s)) goto not_charstring; start = s; s++; while (*s != ' ' && *s) s++; if (strncmp(s, _charstring_definer.c_str(), _charstring_definer.length()) != 0) goto not_charstring; _charstring_len = strtol(start, 0, 10); _charstring_start = (s - str.data()) + _charstring_definer.length(); str.pop_back(); return str.length() <= _charstring_start + _charstring_len; not_charstring: str.pop_back(); return false; } /* PERFORMANCE NOTE: All kinds of speedup tricks tried with eexec -- buffering (doing eexec processing at more_data time), etc., and all this stuff -- and found to have essentially zero effect for PFB fonts. Now, it might be effective for PFAs; but who cares? I hate PFAs. */ bool Type1Reader::next_line(StringAccum &s) { if (_len < 0) return false; // Can't be a charstring if incoming accumulator has nonzero length. _charstring_start = 0; _charstring_len = (s.length() > 0 ? 0 : -1); int first_char = _ungot < 0 ? get() : _ungot; _ungot = -1; for (int c = first_char; c >= 0; c = get()) switch (c) { case '\n': if (test_charstring(s)) goto normal; else { _crlf = 0; goto done; } case '\r': // check for \r\n (counts as only one line ending) if (test_charstring(s)) goto normal; c = get(); if (c != '\n' || preserve_whitespace()) _ungot = c, _crlf = 1; else _crlf = 2; goto done; normal: default: s.append((char)c); break; } done: return true; } int Type1Reader::get_data(unsigned char *data, int len) { if (_len < 0) return -1; if (len <= 0) return 0; int pos = 0; if (_ungot >= 0) { *data++ = _ungot; pos++; _ungot = -1; } for (; pos < len; pos++) { int c = get(); if (c < 0) break; *data++ = c; } return pos; } /***** * Type1PFAReader **/ Type1PFAReader::Type1PFAReader(FILE *f) : _f(f) { } int Type1PFAReader::more_data(unsigned char *data, int len) { size_t size = fread(data, 1, len, _f); return size ? (int)size : -1; } /***** * Type1PFBReader **/ Type1PFBReader::Type1PFBReader(FILE *f) : _f(f), _binary(false), _left(0) { } int Type1PFBReader::more_data(unsigned char *data, int len) { while (_left == 0) { int c = getc(_f); if (c != 128) return -1; c = getc(_f); if (c == 3 || c < 1 || c > 3) return -1; _binary = (c == 2); _left = getc(_f); _left |= getc(_f) << 8; _left |= getc(_f) << 16; _left |= getc(_f) << 24; } if (_left < 0) return -1; if (len > _left) len = _left; _left -= len; return fread(data, 1, len, _f); } bool Type1PFBReader::preserve_whitespace() const { return _binary; } /***** * Type1SubsetReader **/ Type1SubsetReader::Type1SubsetReader(Type1Reader *r, int left) : _reader(r), _left(left) { } int Type1SubsetReader::more_data(unsigned char *data, int len) { if (_left <= 0) return -1; if (len > _left) len = _left; int how_much = _reader->get_data(data, len); if (how_much > 0) _left -= how_much; return how_much; } bool Type1SubsetReader::preserve_whitespace() const { return _reader->preserve_whitespace(); } /***** * Writer **/ Type1Writer::Type1Writer() : _buf(new unsigned char[BufSize]), _pos(0), _eexec(false), _eexec_start(-1), _eexec_end(-1), _lenIV(4) { } Type1Writer::~Type1Writer() { assert(!_pos); delete[] _buf; } inline unsigned char Type1Writer::eexec(int p) { unsigned char c = ((unsigned char)p ^ (_r >> 8)) & 0xFF; _r = ((c + _r) * (uint32_t) t1C1 + t1C2) & 0xFFFF; return c; } void Type1Writer::flush() { local_flush(); } /* PERFORMANCE NOTE: Doing eexec processing during flush -- which streamlines code for the print() methods -- seems to save some time (4-5%). It also makes write performance more consistent. But I have mixed feelings. */ void Type1Writer::local_flush() { if (_eexec_start >= 0 && _eexec_end < 0) _eexec_end = _pos; for (int p = _eexec_start; p < _eexec_end; p++) _buf[p] = eexec(_buf[p]); print0(_buf, _pos); _pos = 0; _eexec_start = _eexec ? 0 : -1; _eexec_end = -1; } void Type1Writer::print(const char *s, int n) { while (n > 0) { if (_pos >= BufSize) local_flush(); int copy = BufSize - _pos; if (copy > n) copy = n; memcpy(_buf + _pos, s, copy); _pos += copy; s += copy; n -= copy; } } Type1Writer & Type1Writer::operator<<(int x) { char str[128]; sprintf(str, "%d", x); print(str, strlen(str)); return *this; } Type1Writer & Type1Writer::operator<<(double x) { char str[256]; sprintf(str, "%g", x); print(str, strlen(str)); return *this; } void Type1Writer::switch_eexec(bool on) { _eexec = on; if (_eexec) { _eexec_start = _pos; _r = t1R_ee; print("SUCK", 4); } else _eexec_end = _pos; } /***** * Type1PFAWriter **/ Type1PFAWriter::Type1PFAWriter(FILE *f) : _f(f), _hex_line(0) { } Type1PFAWriter::~Type1PFAWriter() { flush(); } void Type1PFAWriter::switch_eexec(bool on) { flush(); _hex_line = 0; Type1Writer::switch_eexec(on); } void Type1PFAWriter::print0(const unsigned char *c, int l) { if (eexecing()) { const char *hex = "0123456789ABCDEF"; for (; l; c++, l--) { putc(hex[*c / 16], _f); putc(hex[*c % 16], _f); if (++_hex_line == 39) { putc('\n', _f); _hex_line = 0; } } } else { ssize_t result = fwrite(c, 1, l, _f); (void) result; } } /***** * Type1PFBWriter **/ Type1PFBWriter::Type1PFBWriter(FILE *f) : _f(f), _binary(false) { } Type1PFBWriter::~Type1PFBWriter() { flush(); fputc(128, _f); fputc(3, _f); } void Type1PFBWriter::flush() { Type1Writer::flush(); if (_save.length()) { fputc(128, _f); fputc(_binary ? 2 : 1, _f); long l = _save.length(); fputc(l & 0xFF, _f); fputc((l >> 8) & 0xFF, _f); fputc((l >> 16) & 0xFF, _f); fputc((l >> 24) & 0xFF, _f); ssize_t result = fwrite(_save.data(), 1, _save.length(), _f); (void) result; _save.clear(); } } void Type1PFBWriter::switch_eexec(bool on) { flush(); Type1Writer::switch_eexec(on); _binary = on; } void Type1PFBWriter::print0(const unsigned char *c, int l) { char *m = _save.extend(l); memcpy(m, c, l); } } lcdf-typetools-2.108/libefont/otfdescrip.cc0000644000175000017500000005502613423375327015711 00000000000000/* otfdescrip.cc -- descriptions for OpenType tags * * Copyright (c) 2002-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include struct Mapping { uint32_t tag; const char *description; }; #define T(str) ((str)[0]<<24 | (str)[1]<<16 | (str)[2]<<8 | (str)[3]) static const Mapping scripts[] = { { T("DFLT"), "Default" }, { T("arab"), "Arabic" }, { T("armi"), "Imperial Aramaic" }, { T("armn"), "Armenian" }, { T("avst"), "Avestan" }, { T("bali"), "Balinese" }, { T("bamu"), "Bamum" }, { T("batk"), "Batak" }, { T("beng"), "Bengali" }, { T("bng2"), "Bengali v.2" }, { T("bopo"), "Bopomofo" }, { T("brah"), "Brahmi" }, { T("brai"), "Braille" }, { T("bugi"), "Buginese" }, { T("buhd"), "Buhid" }, { T("byzm"), "Byzantine Music" }, { T("cakm"), "Chakma" }, { T("cans"), "Canadian Syllabics" }, { T("cari"), "Carian" }, { T("cham"), "Cham" }, { T("cher"), "Cherokee" }, { T("copt"), "Coptic" }, { T("cprt"), "Cypriot Syllabary" }, { T("cyrl"), "Cyrillic" }, { T("dev2"), "Devanagari v.2" }, { T("deva"), "Devanagari" }, { T("dsrt"), "Deseret" }, { T("egyp"), "Egyptian heiroglyphs" }, { T("ethi"), "Ethiopic" }, { T("geor"), "Georgian" }, { T("gjr2"), "Gujarati v.2" }, { T("glag"), "Glagolitic" }, { T("goth"), "Gothic" }, { T("grek"), "Greek" }, { T("gujr"), "Gujarati" }, { T("gur2"), "Gurmukhi v.2" }, { T("guru"), "Gurmukhi" }, { T("hang"), "Hangul" }, { T("hani"), "CJK Ideographic" }, { T("hano"), "Hanunoo" }, { T("hebr"), "Hebrew" }, { T("ital"), "Old Italic" }, { T("jamo"), "Hangul Jamo" }, { T("java"), "Javanese" }, { T("kali"), "Kayah Li" }, { T("kana"), "Hiragana/Katakana" }, { T("khar"), "Kharosthi" }, { T("khmr"), "Khmer" }, { T("knd2"), "Kannada v.2" }, { T("knda"), "Kannada" }, { T("kthi"), "Kaithi" }, { T("lana"), "Tai Tham (Lanna)" }, { T("lao "), "Lao" }, { T("latn"), "Latin" }, { T("lepc"), "Lepcha" }, { T("limb"), "Limbu" }, { T("linb"), "Linear B" }, { T("lisu"), "Lisu (Fraser)" }, { T("lyci"), "Lycian" }, { T("lydi"), "Lydian" }, { T("mand"), "Mandaic, Mandaean" }, { T("math"), "Mathematical Alphanumeric Symbols" }, { T("merc"), "Meroitic Cursive" }, { T("mero"), "Meroitic Hieroglyphs" }, { T("mlm2"), "Malayalam v.2" }, { T("mlym"), "Malayalam" }, { T("mong"), "Mongolian" }, { T("mtei"), "Meitei Mayek (Meithei, Meetei)" }, { T("musc"), "Musical Symbols" }, { T("mymr"), "Myanmar" }, { T("nko "), "N'Ko" }, { T("ogam"), "Ogham" }, { T("olck"), "Ol Chiki" }, { T("orkh"), "Old Turkic, Orkhon Runic" }, { T("ory2"), "Odia v.2 (formerly Oriya v.2)" }, { T("orya"), "Odia (formerly Oriya)" }, { T("osma"), "Osmanya" }, { T("phag"), "Phags-pa" }, { T("phli"), "Inscriptional Pahlavi" }, { T("phnx"), "Phoenician" }, { T("prti"), "Inscriptional Parthian" }, { T("rjng"), "Rejang" }, { T("runr"), "Runic" }, { T("samr"), "Samaritan" }, { T("sarb"), "Old South Arabian" }, { T("saur"), "Saurashtra" }, { T("shaw"), "Shavian" }, { T("shrd"), "Sharada" }, { T("sinh"), "Sinhala" }, { T("sora"), "Sora Sompeng" }, { T("sund"), "Sundanese" }, { T("sylo"), "Syloti Nagri" }, { T("syrc"), "Syriac" }, { T("tagb"), "Tagbanwa" }, { T("takr"), "Takri" }, { T("tale"), "Tai Le" }, { T("talu"), "New Tai Lue" }, { T("taml"), "Tamil" }, { T("tavt"), "Tai Viet" }, { T("tel2"), "Telugu v.2" }, { T("telu"), "Telugu" }, { T("tfng"), "Tifinagh" }, { T("tglg"), "Tagalog" }, { T("thaa"), "Thaana" }, { T("thai"), "Thai" }, { T("tibt"), "Tibetan" }, { T("tml2"), "Tamil v.2" }, { T("ugar"), "Ugaritic Cuneiform" }, { T("vai "), "Vai" }, { T("xpeo"), "Old Persian Cuneiform" }, { T("xsux"), "Sumero-Akkadian Cuneiform" }, { T("yi "), "Yi" } }; static const Mapping languages[] = { { T("ABA "), "Abaza" }, { T("ABK "), "Abkhazian" }, { T("ADY "), "Adyghe" }, { T("AFK "), "Afrikaans" }, { T("AFR "), "Afar" }, { T("AGW "), "Agaw" }, { T("ALS "), "Alsatian" }, { T("ALT "), "Altai" }, { T("AMH "), "Amharic" }, { T("APPH"), "Phonetic transcription—Americanist conventions" }, { T("ARA "), "Arabic" }, { T("ARI "), "Aari" }, { T("ARK "), "Arakanese" }, { T("ASM "), "Assamese" }, { T("ATH "), "Athapaskan" }, { T("AVR "), "Avar" }, { T("AWA "), "Awadhi" }, { T("AYM "), "Aymara" }, { T("AZE "), "Azeri" }, { T("BAD "), "Badaga" }, { T("BAG "), "Baghelkhandi" }, { T("BAL "), "Balkar" }, { T("BAU "), "Baule" }, { T("BBR "), "Berber" }, { T("BCH "), "Bench" }, { T("BCR "), "Bible Cree" }, { T("BEL "), "Belarussian" }, { T("BEM "), "Bemba" }, { T("BEN "), "Bengali" }, { T("BGR "), "Bulgarian" }, { T("BHI "), "Bhili" }, { T("BHO "), "Bhojpuri" }, { T("BIK "), "Bikol" }, { T("BIL "), "Bilen" }, { T("BKF "), "Blackfoot" }, { T("BLI "), "Balochi" }, { T("BLN "), "Balante" }, { T("BLT "), "Balti" }, { T("BMB "), "Bambara" }, { T("BML "), "Bamileke" }, { T("BOS "), "Bosnian" }, { T("BRE "), "Breton" }, { T("BRH "), "Brahui" }, { T("BRI "), "Braj Bhasha" }, { T("BRM "), "Burmese" }, { T("BSH "), "Bashkir" }, { T("BTI "), "Beti" }, { T("CAT "), "Catalan" }, { T("CEB "), "Cebuano" }, { T("CHE "), "Chechen" }, { T("CHG "), "Chaha Gurage" }, { T("CHH "), "Chattisgarhi" }, { T("CHI "), "Chichewa" }, { T("CHK "), "Chukchi" }, { T("CHP "), "Chipewyan" }, { T("CHR "), "Cherokee" }, { T("CHU "), "Chuvash" }, { T("CMR "), "Comorian" }, { T("COP "), "Coptic" }, { T("COS "), "Corsican" }, { T("CRE "), "Cree" }, { T("CRR "), "Carrier" }, { T("CRT "), "Crimean Tatar" }, { T("CSL "), "Church Slavonic" }, { T("CSY "), "Czech" }, { T("DAN "), "Danish" }, { T("DAR "), "Dargwa" }, { T("DCR "), "Woods Cree" }, { T("DEU "), "German" }, { T("DGR "), "Dogri" }, { T("DHV "), "Dhivehi" }, // deprecated { T("DIV "), "Dhivehi" }, { T("DJR "), "Djerma" }, { T("DNG "), "Dangme" }, { T("DNK "), "Dinka" }, { T("DRI "), "Dari" }, { T("DUN "), "Dungan" }, { T("DZN "), "Dzongkha" }, { T("EBI "), "Ebira" }, { T("ECR "), "Eastern Cree" }, { T("EDO "), "Edo" }, { T("EFI "), "Efik" }, { T("ELL "), "Greek" }, { T("ENG "), "English" }, { T("ERZ "), "Erzya" }, { T("ESP "), "Spanish" }, { T("ETI "), "Estonian" }, { T("EUQ "), "Basque" }, { T("EVK "), "Evenki" }, { T("EVN "), "Even" }, { T("EWE "), "Ewe" }, { T("FAN "), "French Antillean" }, { T("FAR "), "Farsi" }, { T("FIN "), "Finnish" }, { T("FJI "), "Fijian" }, { T("FLE "), "Flemish" }, { T("FNE "), "Forest Nenets" }, { T("FON "), "Fon" }, { T("FOS "), "Faroese" }, { T("FRA "), "French" }, { T("FRI "), "Frisian" }, { T("FRL "), "Friulian" }, { T("FTA "), "Futa" }, { T("FUL "), "Fulani" }, { T("GAD "), "Ga" }, { T("GAE "), "Gaelic" }, { T("GAG "), "Gagauz" }, { T("GAL "), "Galician" }, { T("GAR "), "Garshuni" }, { T("GAW "), "Garhwali" }, { T("GEZ "), "Ge'ez" }, { T("GIL "), "Gilyak" }, { T("GMZ "), "Gumuz" }, { T("GON "), "Gondi" }, { T("GRN "), "Greenlandic" }, { T("GRO "), "Garo" }, { T("GUA "), "Guarani" }, { T("GUJ "), "Gujarati" }, { T("HAI "), "Haitian" }, { T("HAL "), "Halam" }, { T("HAR "), "Harauti" }, { T("HAU "), "Hausa" }, { T("HAW "), "Hawaiian" }, { T("HBN "), "Hammer-Banna" }, { T("HIL "), "Hiligaynon" }, { T("HIN "), "Hindi" }, { T("HMA "), "High Mari" }, { T("HND "), "Hindko" }, { T("HO "), "Ho" }, { T("HRI "), "Harari" }, { T("HRV "), "Croatian" }, { T("HUN "), "Hungarian" }, { T("HYE "), "Armenian" }, { T("IBO "), "Igbo" }, { T("IJO "), "Ijo" }, { T("ILO "), "Ilokano" }, { T("IND "), "Indonesian" }, { T("ING "), "Ingush" }, { T("INU "), "Inuktitut" }, { T("IPPH"), "Phonetic transcription—IPA conventions" }, { T("IRI "), "Irish" }, { T("IRT "), "Irish Traditional" }, { T("ISL "), "Icelandic" }, { T("ISM "), "Inari Sami" }, { T("ITA "), "Italian" }, { T("IWR "), "Hebrew" }, { T("JAN "), "Japanese" }, { T("JAV "), "Javanese" }, { T("JII "), "Yiddish" }, { T("JUD "), "Judezmo" }, { T("JUL "), "Jula" }, { T("KAB "), "Kabardian" }, { T("KAC "), "Kachchi" }, { T("KAL "), "Kalenjin" }, { T("KAN "), "Kannada" }, { T("KAR "), "Karachay" }, { T("KAT "), "Georgian" }, { T("KAZ "), "Kazakh" }, { T("KEB "), "Kebena" }, { T("KGE "), "Khutsuri Georgian" }, { T("KHA "), "Khakass" }, { T("KHK "), "Khanty-Kazim" }, { T("KHM "), "Khmer" }, { T("KHS "), "Khanty-Shurishkar" }, { T("KHV "), "Khanty-Vakhi" }, { T("KHW "), "Khowar" }, { T("KIK "), "Kikuyu" }, { T("KIR "), "Kirghiz" }, { T("KIS "), "Kisii" }, { T("KKN "), "Kokni" }, { T("KLM "), "Kalmyk" }, { T("KMB "), "Kamba" }, { T("KMN "), "Kumaoni" }, { T("KMO "), "Komo" }, { T("KMS "), "Komso" }, { T("KNR "), "Kanuri" }, { T("KOD "), "Kodagu" }, { T("KOH "), "Korean Old Hangul" }, { T("KOK "), "Konkani" }, { T("KON "), "Kikongo" }, { T("KOP "), "Komi-Permyak" }, { T("KOR "), "Korean" }, { T("KOZ "), "Komi-Zyrian" }, { T("KPL "), "Kpelle" }, { T("KRI "), "Krio" }, { T("KRK "), "Karakalpak" }, { T("KRL "), "Karelian" }, { T("KRM "), "Karaim" }, { T("KRN "), "Karen" }, { T("KRT "), "Koorete" }, { T("KSH "), "Kashmiri" }, { T("KSI "), "Khasi" }, { T("KSM "), "Kildin Sami" }, { T("KUI "), "Kui" }, { T("KUL "), "Kulvi" }, { T("KUM "), "Kumyk" }, { T("KUR "), "Kurdish" }, { T("KUU "), "Kurukh" }, { T("KUY "), "Kuy" }, { T("KYK "), "Koryak" }, { T("LAD "), "Ladin" }, { T("LAH "), "Lahuli" }, { T("LAK "), "Lak" }, { T("LAM "), "Lambani" }, { T("LAO "), "Lao" }, { T("LAT "), "Latin" }, { T("LAZ "), "Laz" }, { T("LCR "), "L-Cree" }, { T("LDK "), "Ladakhi" }, { T("LEZ "), "Lezgi" }, { T("LIN "), "Lingala" }, { T("LMA "), "Low Mari" }, { T("LMB "), "Limbu" }, { T("LMW "), "Lomwe" }, { T("LSB "), "Lower Sorbian" }, { T("LSM "), "Lule Sami" }, { T("LTH "), "Lithuanian" }, { T("LTZ "), "Luxembourgish" }, { T("LUB "), "Luba" }, { T("LUG "), "Luganda" }, { T("LUH "), "Luhya" }, { T("LUO "), "Luo" }, { T("LVI "), "Latvian" }, { T("MAJ "), "Majang" }, { T("MAK "), "Makua" }, { T("MAL "), "Malayalam Traditional" }, { T("MAN "), "Mansi" }, { T("MAP "), "Mapudungun" }, { T("MAR "), "Marathi" }, { T("MAW "), "Marwari" }, { T("MBN "), "Mbundu" }, { T("MCH "), "Manchu" }, { T("MCR "), "Moose Cree" }, { T("MDE "), "Mende" }, { T("MEN "), "Me'en" }, { T("MIZ "), "Mizo" }, { T("MKD "), "Macedonian" }, { T("MLE "), "Male" }, { T("MLG "), "Malagasy" }, { T("MLN "), "Malinke" }, { T("MLR "), "Malayalam Reformed" }, { T("MLY "), "Malay" }, { T("MND "), "Mandinka" }, { T("MNG "), "Mongolian" }, { T("MNI "), "Manipuri" }, { T("MNK "), "Maninka" }, { T("MNX "), "Manx Gaelic" }, { T("MOH "), "Mohawk" }, { T("MOK "), "Moksha" }, { T("MOL "), "Moldavian" }, { T("MON "), "Mon" }, { T("MOR "), "Moroccan" }, { T("MRI "), "Maori" }, { T("MTH "), "Maithili" }, { T("MTS "), "Maltese" }, { T("MUN "), "Mundari" }, { T("NAG "), "Naga-Assamese" }, { T("NAN "), "Nanai" }, { T("NAS "), "Naskapi" }, { T("NCR "), "N-Cree" }, { T("NDB "), "Ndebele" }, { T("NDG "), "Ndonga" }, { T("NEP "), "Nepali" }, { T("NEW "), "Newari" }, { T("NGR "), "Nagari" }, { T("NHC "), "Norway House Cree" }, { T("NIS "), "Nisi" }, { T("NIU "), "Niuean" }, { T("NKL "), "Nkole" }, { T("NKO "), "N'Ko" }, { T("NLD "), "Dutch" }, { T("NOG "), "Nogai" }, { T("NOR "), "Norwegian" }, { T("NSM "), "Northern Sami" }, { T("NTA "), "Northern Tai" }, { T("NTO "), "Esperanto" }, { T("NYN "), "Nynorsk" }, { T("OCI "), "Occitan" }, { T("OCR "), "Oji-Cree" }, { T("OJB "), "Ojibway" }, { T("ORI "), "Odia (formerly Oriya)" }, { T("ORO "), "Oromo" }, { T("OSS "), "Ossetian" }, { T("PAA "), "Palestinian Aramaic" }, { T("PAL "), "Pali" }, { T("PAN "), "Punjabi" }, { T("PAP "), "Palpa" }, { T("PAS "), "Pashto" }, { T("PGR "), "Polytonic Greek" }, { T("PIL "), "Filipino" }, { T("PLG "), "Palaung" }, { T("PLK "), "Polish" }, { T("PRO "), "Provencal" }, { T("PTG "), "Portuguese" }, { T("QIN "), "Chin" }, { T("RAJ "), "Rajasthani" }, { T("RBU "), "Russian Buriat" }, { T("RCR "), "R-Cree" }, { T("RIA "), "Riang" }, { T("RMS "), "Rhaeto-Romanic" }, { T("ROM "), "Romanian" }, { T("ROY "), "Romany" }, { T("RSY "), "Rusyn" }, { T("RUA "), "Ruanda" }, { T("RUS "), "Russian" }, { T("SAD "), "Sadri" }, { T("SAN "), "Sanskrit" }, { T("SAT "), "Santali" }, { T("SAY "), "Sayisi" }, { T("SEK "), "Sekota" }, { T("SEL "), "Selkup" }, { T("SGO "), "Sango" }, { T("SHN "), "Shan" }, { T("SIB "), "Sibe" }, { T("SID "), "Sidamo" }, { T("SIG "), "Silte Gurage" }, { T("SKS "), "Skolt Sami" }, { T("SKY "), "Slovak" }, { T("SLA "), "Slavey" }, { T("SLV "), "Slovenian" }, { T("SML "), "Somali" }, { T("SMO "), "Samoan" }, { T("SNA "), "Sena" }, { T("SND "), "Sindhi" }, { T("SNH "), "Sinhalese" }, { T("SNK "), "Soninke" }, { T("SOG "), "Sodo Gurage" }, { T("SOT "), "Sotho" }, { T("SQI "), "Albanian" }, { T("SRB "), "Serbian" }, { T("SRK "), "Saraiki" }, { T("SRR "), "Serer" }, { T("SSL "), "South Slavey" }, { T("SSM "), "Southern Sami" }, { T("SUR "), "Suri" }, { T("SVA "), "Svan" }, { T("SVE "), "Swedish" }, { T("SWA "), "Swadaya Aramaic" }, { T("SWK "), "Swahili" }, { T("SWZ "), "Swazi" }, { T("SXT "), "Sutu" }, { T("SYR "), "Syriac" }, { T("TAB "), "Tabasaran" }, { T("TAJ "), "Tajiki" }, { T("TAM "), "Tamil" }, { T("TAT "), "Tatar" }, { T("TCR "), "TH-Cree" }, { T("TEL "), "Telugu" }, { T("TGN "), "Tongan" }, { T("TGR "), "Tigre" }, { T("TGY "), "Tigrinya" }, { T("THA "), "Thai" }, { T("THT "), "Tahitian" }, { T("TIB "), "Tibetan" }, { T("TKM "), "Turkmen" }, { T("TMN "), "Temne" }, { T("TNA "), "Tswana" }, { T("TNE "), "Tundra Nenets" }, { T("TNG "), "Tonga" }, { T("TOD "), "Todo" }, { T("TRK "), "Turkish" }, { T("TSG "), "Tsonga" }, { T("TUA "), "Turoyo Aramaic" }, { T("TUL "), "Tulu" }, { T("TUR "), "Turkish" }, // deprecated? { T("TUV "), "Tuvin" }, { T("TWI "), "Twi" }, { T("UDM "), "Udmurt" }, { T("UKR "), "Ukrainian" }, { T("URD "), "Urdu" }, { T("USB "), "Upper Sorbian" }, { T("UYG "), "Uyghur" }, { T("UZB "), "Uzbek" }, { T("VEN "), "Venda" }, { T("VIT "), "Vietnamese" }, { T("WA "), "Wa" }, { T("WAG "), "Wagdi" }, { T("WCR "), "West-Cree" }, { T("WEL "), "Welsh" }, { T("WLF "), "Wolof" }, { T("XBD "), "Tai Lue" }, { T("XHS "), "Xhosa" }, { T("YAK "), "Sakha" }, { T("YBA "), "Yoruba" }, { T("YCR "), "Y-Cree" }, { T("YIC "), "Yi Classic" }, { T("YIM "), "Yi Modern" }, { T("ZHH "), "Chinese, Hong Kong SAR" }, { T("ZHP "), "Chinese Phonetic" }, { T("ZHS "), "Chinese Simplified" }, { T("ZHT "), "Chinese Traditional" }, { T("ZND "), "Zande" }, { T("ZUL "), "Zulu" } }; static const Mapping features[] = { { T("aalt"), "Access All Alternates" }, { T("abvf"), "Above-base Forms" }, { T("abvm"), "Above-base Mark Positioning" }, { T("abvs"), "Above-base Substitutions" }, { T("afrc"), "Alternative Fractions" }, { T("akhn"), "Akhands" }, { T("blwf"), "Below-base Forms" }, { T("blwm"), "Below-base Mark Positioning" }, { T("blws"), "Below-base Substitutions" }, { T("c2pc"), "Petite Capitals From Capitals" }, { T("c2sc"), "Small Capitals From Capitals" }, { T("calt"), "Contextual Alternates" }, { T("case"), "Case-Sensitive Forms" }, { T("ccmp"), "Glyph Composition/Decomposition" }, { T("cfar"), "Conjunct Form After Ro" }, { T("cjct"), "Conjunct Forms" }, { T("clig"), "Contextual Ligatures" }, { T("cpct"), "Centered CJK Punctuation" }, { T("cpsp"), "Capital Spacing" }, { T("cswh"), "Contextual Swash" }, { T("curs"), "Cursive Positioning" }, { T("cv01"), "Character Variants 1" }, { T("cv02"), "Character Variants 2" }, { T("cv03"), "Character Variants 3" }, { T("cv04"), "Character Variants 4" }, { T("cv05"), "Character Variants 5" }, { T("cv06"), "Character Variants 6" }, // ... up to cv99 { T("dist"), "Distances" }, { T("dlig"), "Discretionary Ligatures" }, { T("dnom"), "Denominators" }, { T("expt"), "Expert Forms" }, { T("falt"), "Final Glyph on Line Alternates" }, { T("fin2"), "Terminal Forms #2" }, { T("fin3"), "Terminal Forms #3" }, { T("fina"), "Terminal Forms" }, { T("frac"), "Fractions" }, { T("fwid"), "Full Widths" }, { T("half"), "Half Forms" }, { T("haln"), "Halant Forms" }, { T("halt"), "Alternate Half Widths" }, { T("hist"), "Historical Forms" }, { T("hkna"), "Horizontal Kana Alternates" }, { T("hlig"), "Historical Ligatures" }, { T("hngl"), "Hangul" }, { T("hojo"), "Hojo Kanji Forms (JIS X 0212-1990 Kanji Forms)" }, { T("hwid"), "Half Widths" }, { T("init"), "Initial Forms" }, { T("isol"), "Isolated Forms" }, { T("ital"), "Italics" }, { T("jalt"), "Justification Alternates" }, { T("jp04"), "JIS2004 Forms" }, { T("jp78"), "JIS78 Forms" }, { T("jp83"), "JIS83 Forms" }, { T("jp90"), "JIS90 Forms" }, { T("kern"), "Kerning" }, { T("lfbd"), "Left Bounds" }, { T("liga"), "Standard Ligatures" }, { T("ljmo"), "Leading Jamo Forms" }, { T("lnum"), "Lining Figures" }, { T("locl"), "Localized Forms" }, { T("ltra"), "Left-to-right alternates" }, { T("ltrm"), "Left-to-right mirrored forms" }, { T("mark"), "Mark Positioning" }, { T("med2"), "Medial Forms #2" }, { T("medi"), "Medial Forms" }, { T("mgrk"), "Mathematical Greek" }, { T("mkmk"), "Mark to Mark Positioning" }, { T("mset"), "Mark Positioning via Substitution" }, { T("nalt"), "Alternate Annotation Forms" }, { T("nlck"), "NLC Kanji Forms" }, { T("nukt"), "Nukta Forms" }, { T("numr"), "Numerators" }, { T("onum"), "Oldstyle Figures" }, { T("opbd"), "Optical Bounds" }, { T("ordn"), "Ordinals" }, { T("ornm"), "Ornaments" }, { T("palt"), "Proportional Alternate Widths" }, { T("pcap"), "Petite Capitals" }, { T("pkna"), "Proportional Kana" }, { T("pnum"), "Proportional Figures" }, { T("pref"), "Pre-Base Forms" }, { T("pres"), "Pre-base Substitutions" }, { T("pstf"), "Post-base Forms" }, { T("psts"), "Post-base Substitutions" }, { T("pwid"), "Proportional Widths" }, { T("qwid"), "Quarter Widths" }, { T("rand"), "Randomize" }, { T("rkrf"), "Rakar Forms" }, { T("rlig"), "Required Ligatures" }, { T("rphf"), "Reph Forms" }, { T("rtbd"), "Right Bounds" }, { T("rtla"), "Right-to-left Alternates" }, { T("rtlm"), "Right-to-left Mirrored Forms" }, { T("ruby"), "Ruby Notation Forms" }, { T("salt"), "Stylistic Alternates" }, { T("sinf"), "Scientific Inferiors" }, { T("size"), "Optical Size" }, { T("smcp"), "Small Capitals" }, { T("smpl"), "Simplified Forms" }, { T("ss01"), "Stylistic Set 1" }, { T("ss02"), "Stylistic Set 2" }, { T("ss03"), "Stylistic Set 3" }, { T("ss04"), "Stylistic Set 4" }, { T("ss05"), "Stylistic Set 5" }, { T("ss06"), "Stylistic Set 6" }, { T("ss07"), "Stylistic Set 7" }, { T("ss08"), "Stylistic Set 8" }, { T("ss09"), "Stylistic Set 9" }, { T("ss10"), "Stylistic Set 10" }, { T("ss11"), "Stylistic Set 11" }, { T("ss12"), "Stylistic Set 12" }, { T("ss13"), "Stylistic Set 13" }, { T("ss14"), "Stylistic Set 14" }, { T("ss15"), "Stylistic Set 15" }, { T("ss16"), "Stylistic Set 16" }, { T("ss17"), "Stylistic Set 17" }, { T("ss18"), "Stylistic Set 18" }, { T("ss19"), "Stylistic Set 19" }, { T("ss20"), "Stylistic Set 20" }, { T("subs"), "Subscript" }, { T("sups"), "Superscript" }, { T("swsh"), "Swash" }, { T("titl"), "Titling" }, { T("tjmo"), "Trailing Jamo Forms" }, { T("tnam"), "Traditional Name Forms" }, { T("tnum"), "Tabular Figures" }, { T("trad"), "Traditional Forms" }, { T("twid"), "Third Widths" }, { T("unic"), "Unicase" }, { T("valt"), "Alternate Vertical Metrics" }, { T("vatu"), "Vattu Variants" }, { T("vert"), "Vertical Writing" }, { T("vhal"), "Alternate Vertical Half Metrics" }, { T("vjmo"), "Vowel Jamo Forms" }, { T("vkna"), "Vertical Kana Alternates" }, { T("vkrn"), "Vertical Kerning" }, { T("vpal"), "Proportional Alternate Vertical Metrics" }, { T("vrt2"), "Vertical Alternates and Rotation" }, { T("zero"), "Slashed Zero" } }; namespace Efont { namespace OpenType { static const char * find_description(uint32_t tag, const Mapping *maps, int n) { // should use STL... int l = 0, r = n; while (l < r) { int m = l + (r - l) / 2; if (maps[m].tag < tag) l = m + 1; else if (maps[m].tag == tag) return maps[m].description; else r = m; } return 0; } const char * Tag::script_description() const { return find_description(value(), scripts, sizeof(scripts) / sizeof(Mapping)); } const char * Tag::language_description() const { return find_description(value(), languages, sizeof(languages) / sizeof(Mapping)); } const char * Tag::feature_description() const { return find_description(value(), features, sizeof(features) / sizeof(Mapping)); } }} lcdf-typetools-2.108/libefont/otf.cc0000644000175000017500000013064013423375327014333 00000000000000// -*- related-file-name: "../include/efont/otf.hh" -*- /* otf.{cc,hh} -- OpenType font basics * * Copyright (c) 2002-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include // for ntohl() #include #include namespace Efont { namespace OpenType { Vector debug_glyph_names; Font::Font(const String& s, ErrorHandler* errh) : _str(s), _units_per_em(0) { _str.align(4); _error = parse_header(errh ? errh : ErrorHandler::silent_handler()); } int Font::parse_header(ErrorHandler *errh) { // HEADER FORMAT: // Fixed sfnt version // USHORT numTables // USHORT searchRange // USHORT entrySelector // USHORT rangeShift int len = length(); const uint8_t *data = this->data(); if (HEADER_SIZE > len) return errh->error("OTF file corrupted (too small)"), -EFAULT; if ((data[0] != 'O' || data[1] != 'T' || data[2] != 'T' || data[3] != 'O') && (data[0] != '\000' || data[1] != '\001')) return errh->error("not an OpenType font (bad magic number)"), -ERANGE; int ntables = Data::u16_aligned(data + 4); if (ntables == 0) return errh->error("OTF contains no tables"), -EINVAL; if (HEADER_SIZE + TABLE_DIR_ENTRY_SIZE * ntables > len) return errh->error("OTF table directory out of range"), -EFAULT; // TABLE DIRECTORY ENTRY FORMAT: // ULONG tag // ULONG checksum // ULONG offset // ULONG length uint32_t last_tag = 0U; for (int i = 0; i < ntables; i++) { int loc = HEADER_SIZE + TABLE_DIR_ENTRY_SIZE * i; uint32_t tag = Data::u32_aligned(data + loc); uint32_t offset = Data::u32_aligned(data + loc + 8); uint32_t length = Data::u32_aligned(data + loc + 12); if (tag <= last_tag) return errh->error("tags out of order"), -EINVAL; if (offset + length > (uint32_t) len) return errh->error("OTF data for %<%s%> out of range", Tag(tag).text().c_str()), -EFAULT; if (Tag::head_tag() == tag) { Head head(_str.substring(offset, length)); _units_per_em = head.units_per_em(); } last_tag = tag; } return 0; } bool Font::check_checksums(ErrorHandler *errh) const { if (error() < 0) return false; int nt = ntables(); bool ok = true; for (int i = 0; i < nt; i++) { const uint8_t *entry = data() + HEADER_SIZE + TABLE_DIR_ENTRY_SIZE * i; String tbl = _str.substring(Data::u32_aligned(entry + 8), Data::u32_aligned(entry + 12)); uint32_t sum = checksum(tbl); if (Data::u32_aligned(entry) == 0x68656164 // 'head' && tbl.length() >= 12) sum -= Data::u32_aligned(tbl.udata() + 8); if (sum != Data::u32_aligned(entry + 4)) { if (errh) errh->error("table %<%s%> checksum error: %x vs. %x", Tag(Data::u32_aligned(entry)).text().c_str(), sum, Data::u32_aligned(entry + 4)); ok = false; } } return ok; } int Font::ntables() const { if (error() < 0) return 0; else return Data::u16_aligned(data() + 4); } String Font::table(Tag tag) const { if (error() < 0) return String(); const uint8_t *entry = tag.table_entry(data() + HEADER_SIZE, Data::u16_aligned(data() + 4), TABLE_DIR_ENTRY_SIZE); if (entry) return _str.substring(Data::u32_aligned(entry + 8), Data::u32_aligned(entry + 12)); else return String(); } bool Font::has_table(Tag tag) const { const uint8_t *entry = 0; if (error() >= 0) entry = tag.table_entry(data() + HEADER_SIZE, Data::u16_aligned(data() + 4), TABLE_DIR_ENTRY_SIZE); return entry != 0; } uint32_t Font::table_checksum(Tag tag) const { if (error() < 0) return 0; const uint8_t *entry = tag.table_entry(data() + HEADER_SIZE, Data::u16_aligned(data() + 4), TABLE_DIR_ENTRY_SIZE); if (entry) return Data::u32_aligned(entry + 4); else return 0; } Tag Font::table_tag(int i) const { if (error() < 0 || i < 0 || i >= ntables()) return Tag(); else return Tag(Data::u32_aligned(data() + HEADER_SIZE + TABLE_DIR_ENTRY_SIZE * i)); } uint32_t Font::checksum(const uint8_t *begin, const uint8_t *end) { uint32_t sum = 0; if (reinterpret_cast(begin) % 4) for (; begin + 3 < end; begin += 4) sum += Data::u32(begin); else for (; begin + 3 < end; begin += 4) sum += Data::u32_aligned(begin); uint32_t leftover = 0; for (int i = 0; i < 4; i++) leftover = (leftover << 8) + (begin < end ? *begin++ : 0); return sum + leftover; } uint32_t Font::checksum(const String &s) { return checksum(reinterpret_cast(s.begin()), reinterpret_cast(s.end())); } namespace { class TagCompar { public: TagCompar(const Vector &tags) : _tags(tags) { } bool operator()(int a, int b) { return _tags[a] < _tags[b]; } const Vector &_tags; }; } Font Font::make(bool truetype, const Vector& tags, const Vector& data) { StringAccum sa; // create offset table { union { uint8_t c[HEADER_SIZE]; uint16_t s[HEADER_SIZE / 2]; uint32_t l[HEADER_SIZE / 4]; } hdr; hdr.l[0] = (truetype ? htonl(0x00010000) : htonl(0x4F54544F)); hdr.s[2] = htons(tags.size()); int entrySelector; for (entrySelector = 0; (2 << entrySelector) <= tags.size(); entrySelector++) /* nada */; hdr.s[3] = htons((1 << entrySelector) * 16); hdr.s[4] = htons(entrySelector); hdr.s[5] = htons((tags.size() - (1 << entrySelector)) * 16); sa.append(&hdr.c[0], HEADER_SIZE); } // sort tags Vector permut; for (int i = 0; i < tags.size(); i++) permut.push_back(i); std::sort(permut.begin(), permut.end(), TagCompar(tags)); // table listing uint32_t offset = HEADER_SIZE + TABLE_DIR_ENTRY_SIZE * tags.size(); for (int *tp = permut.begin(); tp < permut.end(); tp++) { union { uint8_t c[TABLE_DIR_ENTRY_SIZE]; uint32_t l[TABLE_DIR_ENTRY_SIZE / 4]; } tdir; tdir.l[0] = htonl(tags[*tp].value()); // discount current checksum adjustment in head table uint32_t sum = checksum(data[*tp]); if (tags[*tp] == Tag("head") && data[*tp].length() >= 12) sum -= Data::u32(data[*tp].udata() + 8); tdir.l[1] = htonl(sum); tdir.l[2] = htonl(offset); tdir.l[3] = htonl(data[*tp].length()); sa.append(&tdir.c[0], TABLE_DIR_ENTRY_SIZE); offset += (data[*tp].length() + 3) & ~3; } // actual tables for (int *tp = permut.begin(); tp < permut.end(); tp++) { sa << data[*tp]; while (sa.length() % 4) sa << '\0'; } // fix 'head' table for (int i = 0; i < tags.size(); i++) { unsigned char *thdr = sa.udata() + HEADER_SIZE + TABLE_DIR_ENTRY_SIZE * i; if (Data::u32(thdr) == 0x68656164 && Data::u32(thdr + 12) >= 12) { uint32_t offset = Data::u32(thdr + 8); char *head = sa.data() + offset; memset(head + 8, '\0', 4); uint32_t allsum = checksum(reinterpret_cast(sa.data()), reinterpret_cast(sa.data() + sa.length())); uint32_t *adj = reinterpret_cast(head + 8); *adj = htonl(0xB1B0AFBA - allsum); } } return Font(sa.take_string()); } /************************** * Tag * * * **************************/ Tag::Tag(const char *s) : _tag(0) { if (!s) s = ""; for (int i = 0; i < 4; i++) if (*s == 0) _tag = (_tag << 8) | 0x20; else if (*s < 32 || *s > 126) { // don't care if s is signed _tag = 0; return; } else _tag = (_tag << 8) | *s++; if (*s) _tag = 0; } Tag::Tag(const String &s) : _tag(0) { if (s.length() <= 4) { const char *ss = s.data(); for (int i = 0; i < s.length(); i++, ss++) if (*ss < 32 || *ss > 126) { _tag = 0; return; } else _tag = (_tag << 8) | *ss; for (int i = s.length(); i < 4; i++) _tag = (_tag << 8) | 0x20; } } bool Tag::valid() const { uint32_t tag = _tag; for (int i = 0; i < 4; i++, tag >>= 8) if ((tag & 255) < 32 || (tag & 255) > 126) return false; return true; } String Tag::text() const { StringAccum sa; uint32_t tag = _tag; for (int i = 0; i < 4; i++, tag = (tag << 8) | 0x20) if (tag != 0x20202020) { uint8_t c = (tag >> 24) & 255; if (c < 32 || c > 126) sa.snprintf(6, "\\%03o", c); else sa << c; } return sa.take_string(); } String Tag::langsys_text(Tag script, Tag langsys) { if (!langsys.null()) return script.text() + "." + langsys.text(); else return script.text(); } const uint8_t * Tag::table_entry(const uint8_t *table, int n, int entry_size) const { assert(((uintptr_t)table & 1) == 0); int l = 0, r = n; while (l < r) { int m = l + (r - l) / 2; const uint8_t *entry = table + m * entry_size; uint32_t m_tag = Data::u32_aligned16(entry); if (_tag < m_tag) r = m; else if (_tag == m_tag) return entry; else l = m + 1; } return 0; } /************************** * ScriptList * * * **************************/ int ScriptList::assign(const String &str, ErrorHandler *errh) { _str = str; _str.align(4); int result = check_header(errh ? errh : ErrorHandler::silent_handler()); if (result < 0) _str = String(); return result; } int ScriptList::check_header(ErrorHandler *errh) { // HEADER FORMAT: // USHORT scriptCount // 6bytes scriptRecord[] int scriptCount; if (_str.length() < SCRIPTLIST_HEADERSIZE || (scriptCount = Data::u16_aligned(_str.udata()), _str.length() < SCRIPTLIST_HEADERSIZE + scriptCount*SCRIPT_RECSIZE)) return errh->error("OTF ScriptList too short"); // XXX check that scripts are sorted return 0; } int ScriptList::script_offset(Tag script) const { if (_str.length() == 0) return -1; const uint8_t *data = _str.udata(); if (const uint8_t *entry = script.table_entry(data + SCRIPTLIST_HEADERSIZE, Data::u16_aligned(data), SCRIPT_RECSIZE)) return Data::u16_aligned(entry + 4); else return 0; } int ScriptList::check_script(Tag tag, int script_off, ErrorHandler *errh) const { const uint8_t *data = _str.udata(); int langSysCount; if (_str.length() < script_off + SCRIPT_HEADERSIZE || (langSysCount = Data::u16_aligned(data + script_off + 2), (_str.length() < script_off + SCRIPT_HEADERSIZE + langSysCount*LANGSYS_RECSIZE))) return (errh ? errh->error("OTF Script table for %<%s%> out of range", tag.text().c_str()) : -1); // XXX check that langsys are sorted return 0; } int ScriptList::langsys_offset(Tag script, Tag langsys, ErrorHandler *errh) const { int script_off = script_offset(script); if (script_off == 0) { script = Tag("DFLT"); script_off = script_offset(script); } if (script_off <= 0) return script_off; // check script bounds if (check_script(script, script_off, errh) < 0) return -1; // search script table const uint8_t *data = _str.udata(); int langSysCount = Data::u16_aligned(data + script_off + 2); if (const uint8_t *entry = langsys.table_entry(data + script_off + SCRIPT_HEADERSIZE, langSysCount, LANGSYS_RECSIZE)) return script_off + Data::u16_aligned(entry + 4); // return default int defaultLangSys = Data::u16_aligned(data + script_off); if (defaultLangSys != 0) return script_off + defaultLangSys; else return 0; } int ScriptList::language_systems(Vector &script, Vector &langsys, ErrorHandler *errh) const { script.clear(); langsys.clear(); const uint8_t *data = _str.udata(); int nscripts = Data::u16_aligned(data); for (int i = 0; i < nscripts; i++) { Tag script_tag(Data::u32_aligned16(data + SCRIPTLIST_HEADERSIZE + i*SCRIPT_RECSIZE)); int script_off = Data::u16_aligned(data + SCRIPTLIST_HEADERSIZE + i*SCRIPT_RECSIZE + 4); if (check_script(script_tag, script_off, errh) < 0) return -1; const uint8_t *script_table = data + script_off; if (Data::u16_aligned(script_table) != 0) // default LangSys script.push_back(script_tag), langsys.push_back(Tag()); int nlangsys = Data::u16_aligned(script_table + 2); for (int j = 0; j < nlangsys; j++) { Tag langsys_tag(Data::u32_aligned16(script_table + SCRIPT_HEADERSIZE + j*LANGSYS_RECSIZE)); script.push_back(script_tag), langsys.push_back(langsys_tag); } } return 0; } int ScriptList::features(Tag script, Tag langsys, int &required_fid, Vector &fids, ErrorHandler *errh, bool clear_fids) const { required_fid = -1; if (clear_fids) fids.clear(); int offset = langsys_offset(script, langsys); if (offset <= 0) return offset; // check langsys bounds const uint8_t *data = _str.udata(); int featureCount; if (_str.length() < offset + LANGSYS_HEADERSIZE || (featureCount = Data::u16_aligned(data + offset + 4), (_str.length() < offset + LANGSYS_HEADERSIZE + featureCount*FEATURE_RECSIZE))) return (errh ? errh->error("OTF LangSys table for %<%s/%s%> out of range", script.text().c_str(), langsys.text().c_str()) : -1); // search langsys table int f = Data::u16_aligned(data + offset + 2); if (f != 0xFFFF) required_fid = f; data += offset + 6; for (int i = 0; i < featureCount; i++, data += FEATURE_RECSIZE) fids.push_back(Data::u16_aligned(data)); return 0; } /************************** * FeatureList * * * **************************/ int FeatureList::assign(const String &str, ErrorHandler *errh) { _str = str; _str.align(2); int result = check_header(errh ? errh : ErrorHandler::silent_handler()); if (result < 0) _str = String(); return result; } int FeatureList::check_header(ErrorHandler *errh) { int featureCount; if (_str.length() < FEATURELIST_HEADERSIZE || (featureCount = Data::u16_aligned(_str.udata()), _str.length() < FEATURELIST_HEADERSIZE + featureCount*FEATURE_RECSIZE)) return errh->error("OTF FeatureList too short"); return 0; } Tag FeatureList::tag(int fid) const { if (_str.length() == 0) return Tag(); const uint8_t *data = _str.udata(); int nfeatures = Data::u16_aligned(data); if (fid >= 0 && fid < nfeatures) return Tag(Data::u32_aligned16(data + FEATURELIST_HEADERSIZE + fid*FEATURE_RECSIZE)); else return Tag(); } String FeatureList::params(int fid, int length, ErrorHandler *errh, bool old_style_offset) const { if (_str.length() == 0 || length < 0) return String(); if (errh == 0) errh = ErrorHandler::silent_handler(); const uint8_t *data = _str.udata(); int len = _str.length(); int nfeatures = Data::u16_aligned(data); if (fid < 0 || fid >= nfeatures) return errh->error("OTF feature ID %<%d%> out of range", fid), String(); int foff = Data::u16_aligned(data + FEATURELIST_HEADERSIZE + fid*FEATURE_RECSIZE + 4); if (len < foff + FEATURE_HEADERSIZE) return errh->error("OTF LookupList for feature ID %<%d%> too short", fid), String(); int poff = Data::u16_aligned(data + foff); if (poff == 0) return String(); if (!old_style_offset) poff += foff; if (len < poff + length) return errh->error("OTF feature parameters for feature ID %<%d%> out of range", fid), String(); else return _str.substring(poff, length); } String FeatureList::size_params(int fid, const Name &name, ErrorHandler *errh) const { // implement 'size' checks from Read Roberts for (int i = 0; i < 2; i++) { String s = params(fid, 10, errh, i != 0); const uint8_t *data = s.udata(); // errh->message("trying %d %d %d %d %d\n", Data::u16_aligned(data), Data::u16_aligned(data + 2), Data::u16_aligned(data + 4), Data::u16_aligned(data + 6), Data::u16_aligned(data + 8)); if (Data::u16_aligned(data) == 0) // design size == 0 continue; if (Data::u16_aligned(data + 2) == 0 // subfamily ID == 0 && Data::u16_aligned(data + 6) == 0 // range start == 0 && Data::u16_aligned(data + 8) == 0 // range end == 0 && Data::u16_aligned(data + 4) == 0) // menu name ID == 0 return s; if (Data::u16_aligned(data + 6) >= Data::u16_aligned(data + 8) // range start >= range end || Data::u16_aligned(data + 4) < 256 // menu name ID < 256 || Data::u16_aligned(data + 4) > 32767 // menu name ID > 32767 || !name.english_name(Data::u16_aligned(data + 4))) // menu name ID is a name ID defined by the font continue; if (Data::u16_aligned(data) + 1 >= Data::u16_aligned(data + 6) // design size >= range start (with 1 dp grace) && Data::u16_aligned(data) <= Data::u16_aligned(data + 8) + 1) // design size <= range end (with 1 dp grace) return s; else if (i == 1 // old-style feature && Data::u16_aligned(data + 8) <= 1440 // range end <= 144 point && Data::u16_aligned(data) <= 1440) { // design size <= 144 point // some old fonts define a bogus feature with design size // not in range (John Owens, Read Roberts) if (errh) errh->warning("invalid 'size' feature: design size not in range"); return s; } } if (errh) errh->error("no valid 'size' feature data in the 'size' feature"); return String(); } int FeatureList::find(Tag tag, const Vector &fids) const { if (fids.size() == 0 || _str.length() == 0) return -1; const uint8_t *data = _str.udata(); int nfeatures = Data::u16_aligned(data); for (const int *fidp = fids.begin(); fidp != fids.end(); fidp++) if (*fidp >= 0 && *fidp < nfeatures) { uint32_t ftag = Data::u32_aligned16(data + FEATURELIST_HEADERSIZE + (*fidp)*FEATURE_RECSIZE); if (ftag == tag.value()) return *fidp; } return -1; } void FeatureList::filter(Vector &fids, const Vector &sorted_ftags) const { if (_str.length() == 0) fids.clear(); else { std::sort(fids.begin(), fids.end()); // sort fids int i = 0, j = 0; while (i < fids.size() && fids[i] < 0) fids[i++] = 0x7FFFFFFF; // XXX check that feature list is in alphabetical order const uint8_t *data = _str.udata(); int nfeatures = Data::u16_aligned(data); while (i < fids.size() && j < sorted_ftags.size() && fids[i] < nfeatures) { uint32_t ftag = Data::u32_aligned16(data + FEATURELIST_HEADERSIZE + fids[i]*FEATURE_RECSIZE); if (ftag < sorted_ftags[j].value()) { // not an interesting feature // replace featureID with a large number, remove later fids[i] = 0x7FFFFFFF; i++; } else if (ftag == sorted_ftags[j].value()) // interesting feature i++; else // an interesting feature is not available j++; } fids.resize(i); // remove remaining uninteresting features std::sort(fids.begin(), fids.end()); // resort, to move bad ones last while (fids.size() && fids.back() == 0x7FFFFFFF) fids.pop_back(); } } int FeatureList::lookups(int fid, Vector &results, ErrorHandler *errh, bool clear_results) const { if (clear_results) results.clear(); if (_str.length() == 0) return -1; if (errh == 0) errh = ErrorHandler::silent_handler(); const uint8_t *data = _str.udata(); int len = _str.length(); int nfeatures = Data::u16_aligned(data); if (fid < 0 || fid >= nfeatures) return errh->error("OTF feature ID %<%d%> out of range", fid); int foff = Data::u16_aligned(data + FEATURELIST_HEADERSIZE + fid*FEATURE_RECSIZE + 4); int lookupCount; if (len < foff + FEATURE_HEADERSIZE || (lookupCount = Data::u16_aligned(data + foff + 2), len < foff + FEATURE_HEADERSIZE + lookupCount*LOOKUPLIST_RECSIZE)) return errh->error("OTF LookupList for feature ID %<%d%> too short", fid); const uint8_t *ldata = data + foff + FEATURE_HEADERSIZE; for (int j = 0; j < lookupCount; j++, ldata += LOOKUPLIST_RECSIZE) results.push_back(Data::u16_aligned(ldata)); return 0; } int FeatureList::lookups(const Vector &fids, Vector &results, ErrorHandler *errh) const { results.clear(); if (_str.length() == 0) return -1; for (int i = 0; i < fids.size(); i++) if (lookups(fids[i], results, errh, false) < 0) return -1; // sort results and remove duplicates std::sort(results.begin(), results.end()); int *unique_result = std::unique(results.begin(), results.end()); results.resize(unique_result - results.begin()); return 0; } int FeatureList::lookups(const Vector &required_fids, const Vector &fids, const Vector &sorted_ftags, Vector &results, ErrorHandler *errh) const { Vector fidsx(fids); filter(fidsx, sorted_ftags); for (int i = 0; i < required_fids.size(); i++) fidsx.push_back(required_fids[i]); return lookups(fidsx, results, errh); } int FeatureList::lookups(int required_fid, const Vector &fids, const Vector &sorted_ftags, Vector &results, ErrorHandler *errh) const { Vector fidsx(fids); filter(fidsx, sorted_ftags); if (required_fid >= 0) fidsx.push_back(required_fid); return lookups(fidsx, results, errh); } int FeatureList::lookups(const ScriptList &script_list, Tag script, Tag langsys, const Vector &sorted_ftags, Vector &results, ErrorHandler *errh) const { int required_fid; Vector fids; int result = script_list.features(script, langsys, required_fid, fids, errh); if (result >= 0) { filter(fids, sorted_ftags); if (required_fid >= 0) fids.push_back(required_fid); result = lookups(fids, results, errh); } return result; } /************************** * Coverage * * * **************************/ Coverage::Coverage() noexcept { } Coverage::Coverage(Glyph first, Glyph last) noexcept { if (first <= last) { _str = String("\000\002\000\001\000\000\000\000\000\000", 10); uint8_t *data = _str.mutable_udata(); data[4] = first >> 8; data[5] = first & 255; data[6] = last >> 8; data[7] = last & 255; _str.align(2); } } Coverage::Coverage(const Vector &gmap) noexcept { int end = gmap.size(); while (end > 0 && !gmap[end - 1]) --end; if (end > 0) { _str = String::make_uninitialized(8 + end); _str.align(4); uint8_t *data = _str.mutable_udata(); memset(data, 0, 8 + end); data[1] = 3; uint32_t n = 0; const bool *it = gmap.begin(); data += 8; for (int i = 0; i < end; ++i, ++it, ++data) if (*it) { *data = 1; ++n; } n = htonl(n); memcpy(_str.mutable_udata() + 4, &n, 4); } } Coverage::Coverage(const String &str, ErrorHandler *errh, bool do_check) noexcept : _str(str) { _str.align(2); if (do_check) { if (check(errh ? errh : ErrorHandler::silent_handler()) < 0) _str = String(); } else { // check()'s shorten-string side effect const uint8_t *data = _str.udata(); int count = Data::u16_aligned(data + 2); if (data[1] == T_LIST) _str = _str.substring(0, HEADERSIZE + count*LIST_RECSIZE); else _str = _str.substring(0, HEADERSIZE + count*RANGES_RECSIZE); } } int Coverage::check(ErrorHandler *errh) // side effect: shorten string to cover coverage { // HEADER FORMAT: // USHORT coverageFormat // USHORT glyphCount const uint8_t *data = _str.udata(); if (_str.length() < HEADERSIZE) return errh->error("OTF coverage table too small"); int coverageFormat = Data::u16_aligned(data); int count = Data::u16_aligned(data + 2); int len; switch (coverageFormat) { case T_LIST: len = HEADERSIZE + count*LIST_RECSIZE; if (_str.length() < len) return errh->error("OTF coverage table too short (format 1)"); // XXX don't check sorting break; case T_RANGES: len = HEADERSIZE + count*RANGES_RECSIZE; if (_str.length() < len) return errh->error("OTF coverage table too short (format 2)"); // XXX don't check sorting // XXX don't check startCoverageIndexes break; default: return errh->error("OTF coverage table has unknown format %d", coverageFormat); } _str = _str.substring(0, len); return 0; } int Coverage::size() const noexcept { if (_str.length() == 0) return -1; const uint8_t *data = _str.udata(); if (data[1] == T_LIST) return (_str.length() - HEADERSIZE) / LIST_RECSIZE; else if (data[1] == T_RANGES) { data += _str.length() - RANGES_RECSIZE; return Data::u16_aligned(data + 4) + Data::u16_aligned(data + 2) - Data::u16_aligned(data) + 1; } else if (data[1] == T_X_BYTEMAP) return Data::u32_aligned(data + 4); else return -1; } int Coverage::coverage_index(Glyph g) const noexcept { if (_str.length() == 0) return -1; const uint8_t *data = _str.udata(); int count = Data::u16_aligned(data + 2); if (data[1] == T_LIST) { int l = 0, r = count; data += HEADERSIZE; while (l < r) { int m = l + (r - l) / 2; int mval = Data::u16_aligned(data + m * LIST_RECSIZE); if (g < mval) r = m; else if (g == mval) return m; else l = m + 1; } return -1; } else if (data[1] == T_RANGES) { int l = 0, r = count; data += HEADERSIZE; while (l < r) { int m = l + (r - l) / 2; const uint8_t *rec = data + m * RANGES_RECSIZE; if (g < Data::u16_aligned(rec)) r = m; else if (g <= Data::u16_aligned(rec + 2)) return Data::u16_aligned(rec + 4) + g - Data::u16_aligned(rec); else l = m + 1; } return -1; } else if (data[1] == T_X_BYTEMAP) { if (g >= 0 && g < _str.length() - 8 && data[8 + g]) return g; else return -1; } else return -1; } Glyph Coverage::operator[](int cindex) const noexcept { if (_str.length() == 0 || cindex < 0) return 0; const uint8_t *data = _str.udata(); int count = Data::u16_aligned(data + 2); if (data[1] == T_LIST) return (cindex < count ? Data::u16_aligned(data + cindex * LIST_RECSIZE) : 0); else if (data[1] == T_RANGES) { int l = 0, r = count; data += HEADERSIZE; while (l < r) { int m = l + (r - l) / 2; const uint8_t *rec = data + m * RANGES_RECSIZE; int start_cindex = Data::u16_aligned(rec + 4); if (cindex < start_cindex) r = m; else if (cindex < start_cindex + Data::u16_aligned(rec + 2) - Data::u16_aligned(rec)) return Data::u16_aligned(rec) + cindex - start_cindex; else l = m + 1; } return 0; } else return 0; } void Coverage::unparse(StringAccum &sa) const noexcept { const uint8_t *data = _str.udata(); if (_str.length() == 0) sa << "@*#!"; else if (data[1] == T_LIST) { int count = Data::u16_aligned(data + 2); for (int i = 0; i < count; i++) { if (i) sa << ','; sa << Data::u16_aligned(data + HEADERSIZE + i*LIST_RECSIZE); } } else { for (int pos = HEADERSIZE; pos < _str.length(); pos += RANGES_RECSIZE) { Glyph start = Data::u16_aligned(data + pos); Glyph end = Data::u16_aligned(data + pos + 2); if (pos > HEADERSIZE) sa << ','; sa << start; if (end != start) sa << '.' << '.' << end; } } } String Coverage::unparse() const noexcept { StringAccum sa; unparse(sa); return sa.take_string(); } Coverage operator&(const Coverage &a, const Coverage &b) { StringAccum sa; sa << '\000' << '\001' << '\000' << '\000'; if (b.has_fast_covers()) { for (Coverage::iterator ai = a.begin(); ai; ++ai) if (b.covers(*ai)) { uint16_t x = *ai; sa << (char)(x >> 8) << (char)(x & 0xFF); } } else { Coverage::iterator ai = a.begin(), bi = b.begin(); while (ai && bi) { if (*ai < *bi) ai.forward_to(*bi); else if (*ai == *bi) { uint16_t x = *ai; sa << (char)(x >> 8) << (char)(x & 0xFF); ai++, bi++; } else bi.forward_to(*ai); } } int n = (sa.length() - 4) / 2; sa[2] = (n >> 8); sa[3] = (n & 0xFF); return Coverage(sa.take_string(), 0, false); } bool operator<=(const Coverage &a, const Coverage &b) { Coverage::iterator ai = a.begin(), bi = b.begin(); while (ai && bi) { if (*ai != *bi && !bi.forward_to(*ai)) return false; ai++, bi++; } return bi || !ai; } /************************ * Coverage::iterator * * * ************************/ Coverage::iterator::iterator(const String &str, bool is_end) : _str(str), _value(0) { // XXX assume _str has been checked if (!_str.length()) { _pos = 0; return; } // shrink _str to fit the coverage table const uint8_t *data = _str.udata(); int n = Data::u16_aligned(data + 2); switch (Data::u16_aligned(data)) { case T_LIST: _str = _str.substring(0, HEADERSIZE + n*LIST_RECSIZE); normal_pos_setting: _pos = is_end ? _str.length() : HEADERSIZE; _value = _pos >= _str.length() ? 0 : Data::u16_aligned(data + _pos); break; case T_RANGES: _str = _str.substring(0, HEADERSIZE + n*RANGES_RECSIZE); goto normal_pos_setting; case T_X_BYTEMAP: for (_pos = 8; _pos < _str.length() && !data[_pos]; ++_pos) /* do nothing */; _value = _pos >= _str.length() ? 0 : _pos - 8; break; default: _str = String(); _pos = 0; _value = 0; break; } } int Coverage::iterator::coverage_index() const { const uint8_t *data = _str.udata(); assert(_pos < _str.length()); if (data[1] == T_LIST) return (_pos - HEADERSIZE) / LIST_RECSIZE; else if (data[1] == T_RANGES) return Data::u16_aligned(data + _pos + 4) + _value - Data::u16_aligned(data + _pos); else return _pos - 8; } void Coverage::iterator::operator++(int) { const uint8_t *data = _str.udata(); int len = _str.length(); if (_pos >= len || (data[1] == T_RANGES && ++_value <= Data::u16_aligned(data + _pos + 2))) return; switch (data[1]) { case T_LIST: _pos += LIST_RECSIZE; normal_pos_setting: _value = _pos >= len ? 0 : Data::u16_aligned(data + _pos); break; case T_RANGES: _pos += RANGES_RECSIZE; goto normal_pos_setting; case T_X_BYTEMAP: for (++_pos; _pos < len && !data[_pos]; ++_pos) /* do nothing */; _value = _pos >= len ? 0 : _pos - 8; break; } } bool Coverage::iterator::forward_to(Glyph find) { // XXX really should check that this works if (find <= _value) return find == _value; else if (_pos >= _str.length()) return false; const uint8_t *data = _str.udata(); if (data[1] == T_LIST) { // check for "common" case: next element _pos += LIST_RECSIZE; if (_pos >= _str.length()) return false; else if (find <= Data::u16_aligned(data + _pos)) { _value = Data::u16_aligned(data + _pos); return find == _value; } // otherwise, binary search over remaining area int l = ((_pos - HEADERSIZE) / LIST_RECSIZE) + 1; int r = (_str.length() - HEADERSIZE) / LIST_RECSIZE; data += HEADERSIZE; while (l < r) { int m = l + (r - l) / 2; Glyph g = Data::u16_aligned(data + m * LIST_RECSIZE); if (find < g) r = m; else if (find == g) l = r = m; else l = m + 1; } _pos = HEADERSIZE + l * LIST_RECSIZE; _value = (_pos >= _str.length() ? 0 : Data::u16_aligned(data - HEADERSIZE + _pos)); } else if (data[1] == T_RANGES) { // check for "common" case: this or next element if (find <= Data::u16_aligned(data + _pos + 2)) { assert(find >= Data::u16_aligned(data + _pos)); _value = find; return true; } _pos += RANGES_RECSIZE; if (_pos >= _str.length()) return false; else if (find <= Data::u16_aligned(data + _pos + 2)) { _value = (find >= Data::u16_aligned(data + _pos) ? find : Data::u16_aligned(data + _pos)); return find == _value; } // otherwise, binary search over remaining area int l = ((_pos - HEADERSIZE) / RANGES_RECSIZE) + 1; int r = (_str.length() - HEADERSIZE) / RANGES_RECSIZE; data += HEADERSIZE; while (l < r) { int m = l + (r - l) / 2; if (find < Data::u16_aligned(data + m * RANGES_RECSIZE)) r = m; else if (find <= Data::u16_aligned(data + m * RANGES_RECSIZE + 2)) { _pos = HEADERSIZE + m * RANGES_RECSIZE; _value = find; return true; } else l = m + 1; } _pos = HEADERSIZE + l * LIST_RECSIZE; _value = (_pos >= _str.length() ? 0 : Data::u16_aligned(data - HEADERSIZE + _pos)); } else if (data[1] == T_X_BYTEMAP) { _pos = 8 + find; while (_pos < _str.length() && !data[_pos]) ++_pos; _pos = _pos >= _str.length() ? _str.length() : _pos; _value = _pos >= _str.length() ? 0 : _pos - 8; } return find == _value; } /************************** * GlyphSet * * * **************************/ GlyphSet::GlyphSet() { memset(_v, 0, sizeof(_v)); } GlyphSet::GlyphSet(const GlyphSet &o) { for (int i = 0; i < VLEN; i++) if (o._v[i]) { _v[i] = new uint32_t[VULEN]; memcpy(_v[i], o._v[i], sizeof(uint32_t) * VULEN); } else _v[i] = 0; } GlyphSet::~GlyphSet() { for (int i = 0; i < VLEN; i++) delete[] _v[i]; } int GlyphSet::change(Glyph g, bool value) { if ((unsigned)g > MAXGLYPH) return -1; uint32_t *&u = _v[g >> SHIFT]; if (!u) { u = new uint32_t[VULEN]; memset(u, 0, sizeof(uint32_t) * VULEN); } uint32_t mask = (1 << (g & 0x1F)); if (value) u[(g & MASK) >> 5] |= mask; else u[(g & MASK) >> 5] &= ~mask; return 0; } GlyphSet & GlyphSet::operator=(const GlyphSet &o) { if (&o != this) { for (int i = 0; i < VLEN; i++) if (o._v[i]) { if (!_v[i]) _v[i] = new uint32_t[VULEN]; memcpy(_v[i], o._v[i], sizeof(uint32_t) * VULEN); } else if (_v[i]) memset(_v[i], 0, sizeof(uint32_t) * VULEN); } return *this; } /************************** * ClassDef * * * **************************/ ClassDef::ClassDef(const String &str, ErrorHandler *errh) noexcept : _str(str) { _str.align(2); if (check(errh ? errh : ErrorHandler::silent_handler()) < 0) _str = String(); } int ClassDef::check(ErrorHandler *errh) { // HEADER FORMAT: // USHORT coverageFormat // USHORT glyphCount const uint8_t *data = _str.udata(); if (_str.length() < 6) // NB: prevents empty format-2 tables return errh->error("OTF class def table too small"); int classFormat = Data::u16_aligned(data); int len; if (classFormat == T_LIST) { int count = Data::u16_aligned(data + 4); len = LIST_HEADERSIZE + count*LIST_RECSIZE; // XXX don't check sorting } else if (classFormat == T_RANGES) { int count = Data::u16_aligned(data + 2); len = RANGES_HEADERSIZE + count*RANGES_RECSIZE; // XXX don't check sorting } else return errh->error("OTF class def table has unknown format %d", classFormat); if (len > _str.length()) return errh->error("OTF class def table too short"); else { _str = _str.substring(0, len); return 0; } } int ClassDef::lookup(Glyph g) const noexcept { if (_str.length() == 0) return -1; const uint8_t *data = _str.udata(); int coverageFormat = Data::u16_aligned(data); if (coverageFormat == T_LIST) { Glyph start = Data::u16_aligned(data + 2); int count = Data::u16_aligned(data + 4); if (g < start || g >= start + count) return 0; else return Data::u16_aligned(data + LIST_HEADERSIZE + (g - start) * LIST_RECSIZE); } else if (coverageFormat == T_RANGES) { int l = 0, r = Data::u16_aligned(data + 2); data += RANGES_HEADERSIZE; while (l < r) { int m = l + (r - l) / 2; const uint8_t *rec = data + m * RANGES_RECSIZE; if (g < Data::u16_aligned(rec)) r = m; else if (g <= Data::u16_aligned(rec + 2)) return Data::u16_aligned(rec + 4); else l = m + 1; } return 0; } else return 0; } void ClassDef::unparse(StringAccum &sa) const noexcept { const uint8_t *data = _str.udata(); if (_str.length() == 0) sa << "@*#!"; else if (data[1] == T_LIST) { Glyph start = Data::u16_aligned(data + 2); int count = Data::u16_aligned(data + 4); for (int i = 0; i < count; i++) { if (i) sa << ','; sa << start + i << '=' << Data::u16_aligned(data + LIST_HEADERSIZE + i*LIST_RECSIZE); } } else { for (int pos = RANGES_HEADERSIZE; pos < _str.length(); pos += RANGES_RECSIZE) { Glyph start = Data::u16_aligned(data + pos); Glyph end = Data::u16_aligned(data + pos + 2); if (pos > RANGES_HEADERSIZE) sa << ','; sa << start; if (end != start) sa << '.' << '.' << end; sa << '=' << Data::u16_aligned(data + pos + 4); } } } String ClassDef::unparse() const noexcept { StringAccum sa; unparse(sa); return sa.take_string(); } /****************************** * ClassDef::class_iterator * * * ******************************/ ClassDef::class_iterator::class_iterator(const String &str, int pos, int the_class, const Coverage::iterator &coviter) : _str(str), _pos(pos), _class(the_class), _coviter(coviter) { // XXX assume _str has been checked // cannot handle the_class == 0 when coviter doesn't exist if (_class == 0 && !_coviter) throw Error("cannot iterate over ClassDef class 0"); // shrink _str to fit the coverage table, and create a fake coverage // iterator if necessary const uint8_t *data = _str.udata(); if (_str.length()) { switch (Data::u16_aligned(data)) { case T_LIST: { Glyph start = Data::u16_aligned(data + 2); int nglyphs = Data::u16_aligned(data + 4); _str = _str.substring(0, LIST_HEADERSIZE + nglyphs*LIST_RECSIZE); if (!_coviter) _coviter = Coverage(start, start + nglyphs - 1).begin(); if (_class) _coviter.forward_to(start); break; } case T_RANGES: { Glyph start = Data::u16_aligned(data + RANGES_HEADERSIZE); int nranges = Data::u16_aligned(data + 2); _str = _str.substring(0, RANGES_HEADERSIZE + nranges*RANGES_RECSIZE); if (!_coviter) { Glyph end = Data::u16_aligned(data + RANGES_HEADERSIZE + 2 + (nranges - 1)*RANGES_RECSIZE); _coviter = Coverage(start, end).begin(); } if (_class) _coviter.forward_to(start); break; } default: _str = String(); break; } } // move to the first relevant glyph if (_pos >= _str.length()) _pos = _str.length(); else { _pos = 0; (*this)++; } } void ClassDef::class_iterator::increment_class0() { const uint8_t *data = _str.udata(); int len = _str.length(); bool is_list = (data[1] == T_LIST); if (_pos != 0) _coviter++; else _pos = FIRST_POS; if (_pos == FIRST_POS && _coviter) { if (*_coviter < Data::u16_aligned(data + (is_list ? 2 : RANGES_HEADERSIZE))) return; _pos = (is_list ? LIST_HEADERSIZE : RANGES_HEADERSIZE); } while (_pos > 0 && _pos < len && _coviter) { Glyph g = *_coviter; if (is_list) { _pos = LIST_HEADERSIZE + LIST_RECSIZE*(g - Data::u16_aligned(data + 2)); if (_pos >= len) break; else if (Data::u16_aligned(data + _pos) == 0) // _class == 0 return; _coviter++; } else { if (g < Data::u16_aligned(data + _pos)) // in a zero range return; else if (g > Data::u16_aligned(data + _pos + 2)) _pos += RANGES_RECSIZE; else if (Data::u16_aligned(data + _pos + 4) == 0) // _class == 0 return; else _coviter.forward_to(Data::u16_aligned(data + _pos + 2) + 1); } } if (_coviter) _pos = LAST_POS; else _pos = len; } void ClassDef::class_iterator::operator++(int) { if (_class == 0) { increment_class0(); return; } const uint8_t *data = _str.udata(); int len = _str.length(); bool is_list = (data[1] == T_LIST); if (_pos != 0) _coviter++; else _pos = (is_list ? LIST_HEADERSIZE : RANGES_HEADERSIZE); while (_pos < len && _coviter) { Glyph g = *_coviter; if (is_list) { _pos = LIST_HEADERSIZE + LIST_RECSIZE*(g - Data::u16_aligned(data + 2)); if (_pos >= len || Data::u16_aligned(data + _pos) == _class) return; _coviter++; } else { while (_pos < len && (g > Data::u16_aligned(data + _pos + 2) || Data::u16_aligned(data + _pos + 4) != _class)) _pos += RANGES_RECSIZE; // now, _pos >= len, or g <= rec.end && class == rec.class if (_pos >= len || g >= Data::u16_aligned(data + _pos)) return; _coviter.forward_to(Data::u16_aligned(data + _pos)); } } _pos = len; } }} // template instantiations #include lcdf-typetools-2.108/libefont/t1item.cc0000644000175000017500000005152013423375327014745 00000000000000// -*- related-file-name: "../include/efont/t1item.hh" -*- /* t1item.{cc,hh} -- items in a Type 1 font * * Copyright (c) 1998-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #ifndef WIN32 # include #endif #if HAVE_BROKEN_STRTOD # define strtod good_strtod #endif namespace Efont { /***** * Type1NullItem **/ void Type1NullItem::gen(Type1Writer &) { } /***** * Type1CopyItem **/ void Type1CopyItem::gen(Type1Writer &w) { w << _value << '\n'; } /***** * Type1EexecItem **/ void Type1EexecItem::gen(Type1Writer &w) { if (_eexec_on) w << "currentfile eexec\n"; w.switch_eexec(_eexec_on); } /***** * Type1Definition **/ typedef Vector NumVector; Type1Definition::Type1Definition(PermString n, const String &v, PermString d) : _name(n), _val(v), _definer(d) { _val.c_str(); // ensure it ends with '\0' } Type1Definition * Type1Definition::make_string(PermString n, const String &v, PermString d) { Type1Definition *t1d = new Type1Definition(n, "", d); t1d->set_string(v); return t1d; } int Type1Definition::slurp_string(StringAccum &accum, int pos, Type1Reader *reader) { int paren_level = 0; char *s = accum.data() + pos; do { switch (*s++) { case '(': paren_level++; break; case ')': paren_level--; break; case '\\': if (paren_level && *s) s++; break; case 0: if (!reader) return -1; pos = s - accum.data(); accum.append('\n'); // add \n if (!reader->next_line(accum)) return -1; accum.c_str(); // ensure null termination s = accum.data() + pos; break; } } while (paren_level); return s - accum.data(); } int Type1Definition::slurp_proc(StringAccum &accum, int pos, Type1Reader *reader) { int paren_level = 0; int brace_level = 0; char *s = accum.data() + pos; do { switch (*s++) { case '{': if (!paren_level) brace_level++; break; case '}': if (!paren_level) brace_level--; break; case '(': paren_level++; break; case ')': paren_level--; break; case '\\': if (paren_level && *s) s++; break; case '%': if (!paren_level) while (*s != '\n' && *s != '\r' && *s) s++; break; case 0: if (!reader) return -1; pos = s - accum.data(); accum.append('\n'); // add \n if (!reader->next_line(accum)) return -1; accum.c_str(); // ensure null termination s = accum.data() + pos; break; } } while (brace_level); return s - accum.data(); } Type1Definition * Type1Definition::make(StringAccum &accum, Type1Reader *reader, bool force_definition) { char *s = accum.data(); while (isspace((unsigned char) *s)) s++; if (*s != '/') return 0; s++; int name_start_pos = s - accum.data(); // find NAME LENGTH while (!isspace((unsigned char) *s) && *s != '[' && *s != '{' && *s != '(' && *s != ']' && *s != '}' && *s != ')' && *s) s++; if (!*s) return 0; int name_end_pos = s - accum.data(); while (isspace((unsigned char) *s)) s++; int val_pos = s - accum.data(); int val_end_pos = -1; bool check_def = false; if (*s == '}' || *s == ']' || *s == ')' || *s == 0) return 0; else if (*s == '(') val_end_pos = slurp_string(accum, val_pos, reader); else if (*s == '{') val_end_pos = slurp_proc(accum, val_pos, reader); else if (*s == '[') { int brack_level = 0; do { switch (*s++) { case '[': brack_level++; break; case ']': brack_level--; break; case '(': case ')': case 0: return 0; } } while (brack_level); val_end_pos = s - accum.data(); } else { while (!isspace((unsigned char) *s) && *s) s++; val_end_pos = s - accum.data(); if (!force_definition) check_def = true; } if (val_end_pos < 0) return 0; s = accum.data() + val_end_pos; while (isspace((unsigned char) *s)) s++; if (check_def && (s[0] != 'd' || s[1] != 'e' || s[2] != 'f')) if (strncmp(s, "dict def", 8) != 0) return 0; PermString name(accum.data()+name_start_pos, name_end_pos - name_start_pos); PermString def(s, accum.length() - (s - accum.data())); String value = String(accum.data() + val_pos, val_end_pos - val_pos); return new Type1Definition(name, value, def); } void Type1Definition::gen(Type1Writer &w) { w << '/' << _name << ' ' << _val << ' ' << _definer << '\n'; } void Type1Definition::gen(StringAccum &sa) { sa << '/' << _name << ' ' << _val << ' ' << _definer; } bool Type1Definition::value_bool(bool &b) const { if (_val == "true") { b = true; return true; } else if (_val == "false") { b = false; return true; } else return false; } bool Type1Definition::value_int(int &i) const { char *s; i = strtol(_val.data(), &s, 10); return (*s == 0); } bool Type1Definition::value_num(double &d) const { char *s; d = strtonumber(_val.data(), &s); return (*s == 0); } bool Type1Definition::value_string(String &str) const { if (_val.length() == 0 || _val[0] != '(' || _val.back() != ')') return false; StringAccum sa; int pos, first_pos = 1, len = _val.length() - 1; for (pos = 1; pos < len; pos++) if (_val[pos] == '\\') { sa.append(_val.data() + first_pos, pos - first_pos); pos++; switch (pos < len ? _val[pos] : -1) { case '\r': pos++; if (pos < len && _val[pos] == '\n') pos++; break; case '\n': pos++; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': { int c = _val[pos++] - '0'; for (int i = 1; pos < len && i < 3 && _val[pos] >= '0' && _val[pos] <= '7'; i++, pos++) c = (c << 3) | (_val[pos] - '0'); sa.append((char) c); break; } case 'n': sa << '\n'; pos++; break; case 'r': sa << '\r'; pos++; break; case 't': sa << '\t'; pos++; break; case 'b': sa << '\b'; pos++; break; case 'f': sa << '\f'; pos++; break; default: sa << _val[pos]; pos++; break; } first_pos = pos; } sa.append(_val.data() + first_pos, len - first_pos); str = sa.take_string(); return true; } bool Type1Definition::value_name(PermString &str) const { if (_val.length() == 0 || _val[0] != '/') return false; int pos; for (pos = 1; pos < _val.length(); pos++) if (isspace((unsigned char) _val[pos]) || _val[pos] == '/') return false; str = PermString(_val.data() + 1, pos - 1); return true; } static bool strtonumvec(const char *f, const char **endf, NumVector &v) { v.clear(); char *s = (char *)f; if (*s != '[' && *s != '{') return false; s++; while (1) { while (isspace((unsigned char) *s)) s++; if (isdigit((unsigned char) *s) || *s == '.' || *s == '-') v.push_back( strtonumber(s, &s) ); else { if (endf) *endf = s + 1; return (*s == ']' || *s == '}'); } } } bool Type1Definition::value_numvec(NumVector &v) const { return strtonumvec(_val.data(), 0, v); } static bool strtonumvec_vec(const char *f, const char **endf, Vector &v) { v.clear(); const char *s = f; if (*s != '[' && *s != '{') return false; s++; while (1) { while (isspace((unsigned char) *s)) s++; if (*s == '[' || *s == '{') { NumVector subv; if (!strtonumvec(s, &s, subv)) return false; v.push_back(subv); } else { if (endf) *endf = s + 1; return (*s == ']' || *s == '}'); } } } bool Type1Definition::value_numvec_vec(Vector &v) const { return strtonumvec_vec(_val.data(), 0, v); } bool Type1Definition::value_normalize(Vector &in, Vector &out) const { in.clear(); out.clear(); const char *s = _val.data(); if (*s++ != '[') return false; while (1) { while (isspace((unsigned char) *s)) s++; if (*s == '[') { Vector sub; if (!strtonumvec_vec(s, &s, sub)) return false; NumVector subin; NumVector subout; for (int i = 0; i < sub.size(); i++) if (sub[i].size() == 2) { subin.push_back(sub[i][0]); subout.push_back(sub[i][1]); } else return false; in.push_back(subin); out.push_back(subout); } else return (*s == ']'); } } bool Type1Definition::value_namevec(Vector &v) const { v.clear(); const char *s = _val.data(); if (*s++ != '[') return false; while (1) { while (isspace((unsigned char) *s)) s++; if (*s == '/') s++; if (isalnum((unsigned char) *s)) { const char *start = s; while (*s && !isspace((unsigned char) *s) && *s != ']' && *s != '/') s++; v.push_back(PermString(start, s - start)); } else return (*s == ']'); } } void Type1Definition::set_bool(bool b) { set_val(b ? "true" : "false"); } void Type1Definition::set_int(int i) { set_val(String(i)); } void Type1Definition::set_num(double n) { set_val(String(n)); } void Type1Definition::set_string(const String &v) { const char *s = v.data(); int len = v.length(); int left = 0; StringAccum sa; sa << '('; for (int pos = 0; pos < len; pos++) if ((s[pos] < ' ' && !isspace((unsigned char) s[pos])) || ((unsigned char)s[pos]) > 0176 || s[pos] == '(' || s[pos] == ')' || s[pos] == '\\') { sa << v.substring(left, pos - left) << '\\'; if (s[pos] == '(' || s[pos] == ')' || s[pos] == '\\') sa << s[pos]; else sprintf(sa.reserve(8), "%03o", (unsigned char) (s[pos])); left = pos + 1; } sa << v.substring(left) << ')'; _val = sa.take_string(); } void Type1Definition::set_name(PermString str, bool name) { StringAccum sa; if (name) sa << '/'; sa << str; set_val(sa); } static void accum_numvec(StringAccum &sa, const NumVector &nv, bool executable) { char open = (executable ? '{' : '['); for (int i = 0; i < nv.size(); i++) sa << (i ? ' ' : open) << nv[i]; sa << (executable ? '}' : ']'); } void Type1Definition::set_numvec(const NumVector &nv, bool executable) { StringAccum sa; accum_numvec(sa, nv, executable); set_val(sa); } void Type1Definition::set_numvec_vec(const Vector &nv) { StringAccum sa; sa << '['; for (int i = 0; i < nv.size(); i++) accum_numvec(sa, nv[i], false); sa << ']'; set_val(sa); } void Type1Definition::set_normalize(const Vector &vin, const Vector &vout) { StringAccum sa; sa << '['; for (int i = 0; i < vin.size(); i++) { const NumVector &vini = vin[i]; const NumVector &vouti = vout[i]; sa << '['; for (int j = 0; j < vini.size(); j++) sa << '[' << vini[j] << ' ' << vouti[j] << ']'; sa << ']'; } sa << ']'; set_val(sa); } void Type1Definition::set_namevec(const Vector &v, bool executable) { StringAccum sa; sa << '['; for (int i = 0; i < v.size(); i++) { if (i) sa << ' '; if (executable) sa << '/'; sa << v[i]; } sa << ']'; set_val(sa); } /***** * Type1Encoding **/ static PermString::Initializer initializer; static PermString dot_notdef(".notdef"); Type1Encoding::Type1Encoding() : _v(new PermString[256]), _copy_of(0), _definer("readonly def") { for (int i = 0; i < 256; i++) _v[i] = dot_notdef; } Type1Encoding::Type1Encoding(const Type1Encoding &o) : Type1Item(), _definer(o._definer) { if (o._copy_of) { _v = o._v; _copy_of = o._copy_of; } else { _v = new PermString[256]; _copy_of = 0; for (int i = 0; i < 256; i++) _v[i] = o._v[i]; } } Type1Encoding::Type1Encoding(Type1Encoding *copy_of) : _v(copy_of->_v), _copy_of(copy_of), _definer(copy_of->_definer) { } Type1Encoding::~Type1Encoding() { if (!_copy_of) delete[] _v; } void Type1Encoding::unshare() { if (_copy_of) { PermString *new_v = new PermString[256]; memcpy(new_v, _v, sizeof(PermString) * 256); _v = new_v; _copy_of = 0; } } void Type1Encoding::clear() { unshare(); for (int i = 0; i < 256; i++) _v[i] = dot_notdef; } static Type1Encoding *canonical_standard_encoding; Type1Encoding * Type1Encoding::standard_encoding() { if (!canonical_standard_encoding) { canonical_standard_encoding = new Type1Encoding; for (int i = 0; i < 256; i++) if (Charstring::standard_encoding[i]) canonical_standard_encoding->put(i, Charstring::standard_encoding[i]); } // Return a copy of the cached encoding. When it's deleted, we won't be. return new Type1Encoding(canonical_standard_encoding); } void Type1Encoding::gen(Type1Writer &w) { if (_copy_of && _copy_of == canonical_standard_encoding) w << "/Encoding StandardEncoding def\n"; else { w << "/Encoding 256 array\n0 1 255 {1 index exch /.notdef put} for\n"; for (int i = 0; i < 256; i++) if (_v[i] != dot_notdef) w << "dup " << i << " /" << _v[i] << " put\n"; w << _definer << '\n'; } } /***** * Type1Subr **/ Type1Subr::Type1Subr(PermString n, int num, PermString definer, int lenIV, const String &s) : _name(n), _subrno(num), _definer(definer), _cs(lenIV, s) { } Type1Subr::Type1Subr(PermString n, int num, PermString definer, const Type1Charstring &t1cs) : _name(n), _subrno(num), _definer(definer), _cs(t1cs) { } Type1Subr * Type1Subr::make(const char *s_in, int s_len, int cs_pos, int cs_len, int lenIV) { /* USAGE NOTE: You must ensure that s_in contains a valid subroutine string before calling Type1Subr::make. Type1Reader::was_charstring() is a good guarantee of this. A valid subroutine string is one of the following: /[char_name] ### charstring_start ........ dup [subrno] ### charstring_start .... */ const char *s = s_in; PermString name; int subrno = 0; // Force literal spaces rather than isspace(). if (*s == '/') { const char *nstart = ++s; while (!isspace((unsigned char) *s) && *s) s++; name = PermString(nstart, s - nstart); } else { // dup [subrno] ... s += 3; while (isspace((unsigned char) *s)) s++; subrno = strtol(s, (char **)&s, 10); } s = s_in + cs_pos; // Lazily decrypt the charstring. PermString definer = PermString(s + cs_len, s_len - cs_len - cs_pos); return new Type1Subr(name, subrno, definer, lenIV, String(s, cs_len)); } Type1Subr * Type1Subr::make_subr(int subrno, const Type1Charstring &cs, PermString definer) { return new Type1Subr(PermString(), subrno, definer, cs); } Type1Subr * Type1Subr::make_glyph(PermString glyph, const Type1Charstring &cs, PermString definer) { return new Type1Subr(glyph, -1, definer, cs); } void Type1Subr::gen(Type1Writer &w) { int len = _cs.length(); const unsigned char *data = _cs.data(); if (is_subr()) w << "dup " << _subrno << ' ' << len + w.lenIV() << w.charstring_start(); else w << '/' << _name << ' ' << len + w.lenIV() << w.charstring_start(); if (w.lenIV() < 0) { // lenIV < 0 means charstrings are unencrypted w.print((const char *)data, len); } else { // PERFORMANCE NOTE: Putting the charstring in a buffer of known length // and printing that buffer rather than one char at a time is an OK // optimization. (around 10%) unsigned char *buf = new unsigned char[len + w.lenIV()]; unsigned char *t = buf; int r = t1R_cs; for (int i = 0; i < w.lenIV(); i++) { unsigned char c = (unsigned char)(r >> 8); *t++ = c; r = ((c + r) * (uint32_t) t1C1 + t1C2) & 0xFFFF; } for (int i = 0; i < len; i++, data++) { unsigned char c = (*data ^ (r >> 8)); *t++ = c; r = ((c + r) * (uint32_t) t1C1 + t1C2) & 0xFFFF; } w.print((char *)buf, len + w.lenIV()); delete[] buf; } w << _definer << '\n'; } /***** * Type1SubrGroupItem **/ Type1SubrGroupItem::Type1SubrGroupItem(Type1Font *font, bool is_subrs, const String &value) : _font(font), _is_subrs(is_subrs), _value(value) { } Type1SubrGroupItem::Type1SubrGroupItem(const Type1SubrGroupItem &from, Type1Font *font) : _font(font), _is_subrs(from._is_subrs), _value(from._value), _end_text(from._end_text) { } void Type1SubrGroupItem::add_end_text(const String &s) { _end_text += s + "\n"; } void Type1SubrGroupItem::gen(Type1Writer &w) { Type1Font *font = _font; int pos = _value.find_left(_is_subrs ? " array" : " dict"); if (pos >= 1 && isdigit((unsigned char) _value[pos - 1])) { int numpos = pos - 1; while (numpos >= 1 && isdigit((unsigned char) _value[numpos - 1])) numpos--; int n; if (_is_subrs) { n = font->nsubrs(); while (n && !font->subr(n - 1)) n--; } else n = font->nglyphs(); w << _value.substring(0, numpos) << n << _value.substring(pos); } else w << _value; w << '\n'; if (_is_subrs) { int count = font->nsubrs(); for (int i = 0; i < count; i++) if (Type1Subr *g = font->subr_x(i)) g->gen(w); } else { int count = font->nglyphs(); for (int i = 0; i < count; i++) if (Type1Subr *g = font->glyph_x(i)) g->gen(w); } w << _end_text; } /***** * Type1IncludedFont **/ Type1IncludedFont::Type1IncludedFont(Type1Font *font, int unique_id) : _included_font(font), _unique_id(unique_id) { } Type1IncludedFont::~Type1IncludedFont() { delete _included_font; } void Type1IncludedFont::gen(Type1Writer &w) { FILE *f = tmpfile(); if (!f) return; // write included font Type1PFAWriter new_w(f); _included_font->write(new_w); fflush(f); struct stat s; fstat(fileno(f), &s); w << "FontDirectory /" << _included_font->font_name() << " known{\n" << "/" << _included_font->font_name() << " findfont dup /UniqueID known {dup /UniqueID get " << _unique_id << " eq exch /FontType get 1 eq and}{pop false}ifelse {\nsave userdict/fbufstr 512 string put\n" << (int)(s.st_size / 512) << "{currentfile fbufstr readstring{pop}{clear currentfile\nclosefile/fontdownload/unexpectedEOF/.error cvx exec}ifelse}repeat\ncurrentfile " << (int)(s.st_size % 512) << " string readstring{pop}{clear currentfile\nclosefile/fontdownload/unexpectedEOF/.error cvx exec}ifelse\nrestore}if}if\n"; rewind(f); char str[2048]; while (1) { int r = fread(str, 1, 2048, f); if (r <= 0) break; w.print(str, r); } fclose(f); } } lcdf-typetools-2.108/libefont/otfdata.cc0000644000175000017500000000224713423375327015166 00000000000000// -*- related-file-name: "../include/efont/otfdata.hh" -*- /* otfdata.{cc,hh} -- OpenType bounds-checked string type * * Copyright (c) 2003-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include namespace Efont { namespace OpenType { Data Data::subtable(unsigned offset) const { if (offset > (unsigned) _str.length()) throw Bounds(); return Data(_str.substring(offset)); } Data Data::offset_subtable(unsigned offset_offset) const { int offset = u16(offset_offset); if (offset > _str.length()) throw Bounds(); return Data(_str.substring(offset)); } }} // template instantiations #include lcdf-typetools-2.108/libefont/ttfkern.cc0000644000175000017500000000640513423375327015221 00000000000000// -*- related-file-name: "../include/efont/ttfkern.hh" -*- /* ttfkern.{cc,hh} -- TrueType kern table * * Copyright (c) 2009-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include namespace Efont { namespace OpenType { inline Data KernTable::subtable(uint32_t &off_in_out) const { uint32_t off = off_in_out, len; if (_version == 0) { if (_d.u16(off) != 0) throw new Format("kern subtable"); len = _d.u16(off + 2); } else len = _d.u32(off); if (len < 6 || off + len > (uint32_t) _d.length()) throw new Bounds(); off_in_out = off + len; return _d.substring(off, len); } KernTable::KernTable(const Data &d, ErrorHandler *) : _d(d), _error(-1) { // USHORT Version // USHORT nTables if (d.length() == 0) throw BlankTable("kern"); uint32_t ntables, off; if (d.u16(0) == 0) { ntables = d.u16(2); _version = 0; off = 4; } else if (d.u16(0) == 1) { ntables = d.u32(4); _version = 1; off = 8; } else throw Format("kern"); for (uint32_t i = 0; i < ntables; ++i) (void) subtable(off); _error = 0; } bool KernTable::unparse_automatics(Vector &v, ErrorHandler *errh) const { uint32_t ntables = this->ntables(); uint32_t off = first_offset(); int success = 0; if (_error < 0) return false; for (uint16_t i = 0; i < ntables; ++i) { Data subt = _d.subtable(off); uint16_t coverage = subt.u16(4); if (_version == 0) { if ((coverage & COV_V0_HORIZONTAL) == 0 || (coverage & (COV_V0_MINIMUM | COV_V0_CROSS_STREAM | COV_V0_OVERRIDE)) != 0 || (coverage & COV_V0_FORMAT) != COV_V0_FORMAT0) continue; } else { if ((coverage & (COV_V1_VERTICAL | COV_V1_CROSS_STREAM | COV_V1_VARIATION)) != 0 || (coverage & COV_V1_FORMAT) != COV_V1_FORMAT0) continue; } try { uint32_t off = (_version ? 16 : 14); uint16_t npairs = subt.u16(off - 8); for (uint16_t j = 0; j < npairs; ++j, off += 6) { v.push_back(Positioning(Position(subt.u16(off), 0, 0, subt.s16(off + 4), 0), Position(subt.u16(off + 2), 0, 0, 0, 0))); ++success; } } catch (Error e) { if (errh) errh->warning("%s, continuing", e.description.c_str()); } } return success > 0; } }} #include lcdf-typetools-2.108/libefont/Makefile.in0000644000175000017500000004612613423376574015313 00000000000000# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = libefont ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/lcdf-typetools.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/autoconf.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru AM_V_AR = $(am__v_AR_@AM_V@) am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) am__v_AR_0 = @echo " AR " $@; am__v_AR_1 = libefont_a_AR = $(AR) $(ARFLAGS) libefont_a_DEPENDENCIES = am_libefont_a_OBJECTS = afm.$(OBJEXT) afmparse.$(OBJEXT) \ afmw.$(OBJEXT) amfm.$(OBJEXT) cff.$(OBJEXT) encoding.$(OBJEXT) \ findmet.$(OBJEXT) metrics.$(OBJEXT) otf.$(OBJEXT) \ otfcmap.$(OBJEXT) otfdata.$(OBJEXT) otfdescrip.$(OBJEXT) \ otfgpos.$(OBJEXT) otfgsub.$(OBJEXT) otfname.$(OBJEXT) \ otfos2.$(OBJEXT) otfpost.$(OBJEXT) pairop.$(OBJEXT) \ psres.$(OBJEXT) t1bounds.$(OBJEXT) t1cs.$(OBJEXT) \ t1csgen.$(OBJEXT) t1interp.$(OBJEXT) t1item.$(OBJEXT) \ t1font.$(OBJEXT) t1fontskel.$(OBJEXT) t1mm.$(OBJEXT) \ t1rw.$(OBJEXT) t1unparser.$(OBJEXT) ttfcs.$(OBJEXT) \ ttfhead.$(OBJEXT) ttfkern.$(OBJEXT) libefont_a_OBJECTS = $(am_libefont_a_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(libefont_a_SOURCES) DIST_SOURCES = $(libefont_a_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KPATHSEA_DEPEND = @KPATHSEA_DEPEND@ KPATHSEA_INCLUDES = @KPATHSEA_INCLUDES@ KPATHSEA_LIBS = @KPATHSEA_LIBS@ KPATHSEA_RULE = @KPATHSEA_RULE@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SELECTED_SUBDIRS = @SELECTED_SUBDIRS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TEMPLATE_OBJS = @TEMPLATE_OBJS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ encdir = @encdir@ exec_prefix = @exec_prefix@ glyphlistdir = @glyphlistdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign noinst_LIBRARIES = libefont.a libefont_a_SOURCES = \ afm.cc \ afmparse.cc \ afmw.cc \ amfm.cc \ cff.cc \ encoding.cc \ findmet.cc \ metrics.cc \ otf.cc \ otfcmap.cc \ otfdata.cc \ otfdescrip.cc \ otfgpos.cc \ otfgsub.cc \ otfname.cc \ otfos2.cc \ otfpost.cc \ pairop.cc \ psres.cc \ t1bounds.cc \ t1cs.cc \ t1csgen.cc \ t1interp.cc \ t1item.cc \ t1font.cc \ t1fontskel.cc \ t1mm.cc \ t1rw.cc \ t1unparser.cc \ ttfcs.cc \ ttfhead.cc \ ttfkern.cc libefont_a_LIBADD = @TEMPLATE_OBJS@ CLEANFILES = @TEMPLATE_OBJS@ AM_CPPFLAGS = -I$(srcdir)/../include all: all-am .SUFFIXES: .SUFFIXES: .cc .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign libefont/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign libefont/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libefont.a: $(libefont_a_OBJECTS) $(libefont_a_DEPENDENCIES) $(EXTRA_libefont_a_DEPENDENCIES) $(AM_V_at)-rm -f libefont.a $(AM_V_AR)$(libefont_a_AR) libefont.a $(libefont_a_OBJECTS) $(libefont_a_LIBADD) $(AM_V_at)$(RANLIB) libefont.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/afm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/afmparse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/afmw.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amfm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cff.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/encoding.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findmet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/metrics.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/otf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/otfcmap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/otfdata.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/otfdescrip.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/otfgpos.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/otfgsub.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/otfname.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/otfos2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/otfpost.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pairop.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/psres.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1bounds.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1cs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1csgen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1font.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1fontskel.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1interp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1item.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1mm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1rw.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1unparser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ttfcs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ttfhead.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ttfkern.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lcdf-typetools-2.108/libefont/encoding.cc0000644000175000017500000000153213423375327015326 00000000000000// -*- related-file-name: "../include/efont/encoding.hh" -*- /* encoding.{cc,hh} -- 8-bit encodings * * Copyright (c) 1998-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include namespace Efont { void Encoding8::reserve_glyphs(int count) { if (count <= _codes.size()) return; _codes.resize(count, -1); } } lcdf-typetools-2.108/libefont/ttfhead.cc0000644000175000017500000000446613423375327015170 00000000000000// -*- related-file-name: "../include/efont/ttfhead.hh" -*- /* ttfhead.{cc,hh} -- TrueType head table * * Copyright (c) 2007-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include namespace Efont { namespace OpenType { Head::Head(const String &s, ErrorHandler *errh) : _d(s) { _error = parse_header(errh ? errh : ErrorHandler::silent_handler()); } int Head::parse_header(ErrorHandler *errh) { // HEAD format: // 0 Fixed Table version number 0x00010000 (ver. 1.0) // 4 Fixed fontRevision // 8 ULONG checkSumAdjustment // 12 ULONG magicNumber Set to 0x5F0F3CF5 // 16 USHORT flags // 18 USHORT unitsPerEm // 20 LONGDATETIME created // 28 LONGDATETIME modified // 36 USHORT xMin // 38 SHORT yMin // 40 SHORT xMax // 42 SHORT yMax // 44 USHORT macStyle // 46 USHORT lowestRecPPEM // 48 SHORT fontDirectionHint // 50 SHORT indexToLocFormat // 52 SHORT glyphDataFormat int len = _d.length(); const uint8_t *data = _d.udata(); if (len == 0) return errh->error("font has no 'head' table"), -EFAULT; if (54 > len) return errh->error("'head' table too small"), -EFAULT; if (!(data[0] == '\000' && data[1] == '\001')) return errh->error("bad 'head' version number"), -ERANGE; if (_d.u32(12) != 0x5F0F3CF5) return errh->error("bad 'head' magic number"), -ERANGE; return 0; } }} lcdf-typetools-2.108/libefont/otfos2.cc0000644000175000017500000000252113423375327014753 00000000000000// -*- related-file-name: "../include/efont/otfos2.hh" -*- /* otfos2.{cc,hh} -- OpenType OS/2 table * * Copyright (c) 2005-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include namespace Efont { namespace OpenType { Os2::Os2(const Data &data, ErrorHandler *errh) : _data(data) { _error = parse_header(errh ? errh : ErrorHandler::silent_handler()); if (_error < 0) _data = Data(); } int Os2::parse_header(ErrorHandler *errh) { // HEADER FORMAT: // USHORT version if (HEADER_SIZE > _data.length()) return errh->error("OTF OS/2 table too small"), -EFAULT; if (_data.u16(0) > 5) return errh->error("unexpected OS/2 version number %d", _data.u16(0)), -ERANGE; return 0; } }} lcdf-typetools-2.108/libefont/metrics.cc0000644000175000017500000000611613423375327015211 00000000000000// -*- related-file-name: "../include/efont/metrics.hh" -*- /* metrics.{cc,hh} -- generic font metrics * * Copyright (c) 1998-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include /* for UNKDOUBLE */ namespace Efont { Metrics::Metrics() : _name_map(-1), _scale(1), _fdv(fdLast, UNKDOUBLE), _xt_map(0), _uses(0) { _xt.push_back((MetricsXt *)0); } Metrics::Metrics(PermString font_name, PermString full_name, const Metrics &m) : _font_name(font_name), _family(m._family), _full_name(full_name), _version(m._version), _name_map(m._name_map), _names(m._names), _encoding(m._encoding), _scale(1), _fdv(fdLast, UNKDOUBLE), _pairp(m._pairp), _xt_map(0), _uses(0) { reserve_glyphs(m._wdv.size()); _kernv.resize(m._kernv.size(), UNKDOUBLE); _xt.push_back((MetricsXt *)0); } Metrics::~Metrics() { assert(_uses == 0); for (int i = 1; i < _xt.size(); i++) delete _xt[i]; } void Metrics::set_font_name(PermString n) { assert(!_font_name); _font_name = n; } void Metrics::reserve_glyphs(int amt) { if (amt <= _wdv.size()) return; _wdv.resize(amt, UNKDOUBLE); _lfv.resize(amt, UNKDOUBLE); _rtv.resize(amt, UNKDOUBLE); _tpv.resize(amt, UNKDOUBLE); _btv.resize(amt, UNKDOUBLE); _encoding.reserve_glyphs(amt); _pairp.reserve_glyphs(amt); for (int i = 1; i < _xt.size(); i++) _xt[i]->reserve_glyphs(amt); } GlyphIndex Metrics::add_glyph(PermString n) { if (nglyphs() >= _wdv.size()) reserve_glyphs(nglyphs() ? nglyphs() * 2 : 64); GlyphIndex gi = _names.size(); _names.push_back(n); _name_map.insert(n, gi); return gi; } static void set_dimen(Vector &dest, const Vector &src, double scale, bool increment) { int c = src.size(); if (increment) for (int i = 0; i < c; i++) dest.at_u(i) += src.at_u(i) * scale; else if (scale < 0.9999 || scale > 1.0001) for (int i = 0; i < c; i++) dest.at_u(i) = src.at_u(i) * scale; else dest = src; } void Metrics::interpolate_dimens(const Metrics &m, double scale, bool increment) { set_dimen(_fdv, m._fdv, scale, increment); set_dimen(_wdv, m._wdv, scale, increment); set_dimen(_lfv, m._lfv, scale, increment); set_dimen(_rtv, m._rtv, scale, increment); set_dimen(_tpv, m._tpv, scale, increment); set_dimen(_btv, m._btv, scale, increment); set_dimen(_kernv, m._kernv, scale, increment); } void Metrics::add_xt(MetricsXt *mxt) { int n = _xt.size(); _xt.push_back(mxt); _xt_map.insert(mxt->kind(), n); if (_wdv.size() > 0) mxt->reserve_glyphs(_wdv.size()); } } lcdf-typetools-2.108/libefont/t1csgen.cc0000644000175000017500000004114413423375327015107 00000000000000// -*- related-file-name: "../include/efont/t1csgen.hh" -*- /* t1csgen.{cc,hh} -- Type 1 charstring generation * * Copyright (c) 1998-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include namespace Efont { static const char * const command_desc[] = { 0, 0, 0, 0, "y", "xy", "x", "y", "xyxyxy", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "xy", "x", 0, 0, 0, 0, 0, 0, 0, "yxyx", "xxyy", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "XY", 0, 0, 0, 0 }; Type1CharstringGen::Type1CharstringGen(int precision) { if (precision >= 1 && precision <= 107) _precision = precision; else _precision = 5; _f_precision = _precision; clear(); } void Type1CharstringGen::clear() { _ncs.clear(); _true = _false = Point(0, 0); _state = S_INITIAL; } void Type1CharstringGen::gen_rational(int big_val, int divisor) { int frac = big_val % divisor; int val = (frac == 0 ? big_val / divisor : big_val); if (val >= -107 && val <= 107) _ncs.append((char)(val + 139)); else if (val >= -1131 && val <= 1131) { int base = val < 0 ? 251 : 247; if (val < 0) val = -val; val -= 108; int w = val % 256; val = (val - w) / 256; _ncs.append((char)(val + base)); _ncs.append((char)w); } else { _ncs.append('\377'); long l = val; _ncs.append((char)((l >> 24) & 0xFF)); _ncs.append((char)((l >> 16) & 0xFF)); _ncs.append((char)((l >> 8) & 0xFF)); _ncs.append((char)((l >> 0) & 0xFF)); } if (frac != 0) { _ncs.append((char)(divisor + 139)); _ncs.append((char)Charstring::cEscape); _ncs.append((char)(Charstring::cDiv - Charstring::cEscapeDelta)); } } void Type1CharstringGen::gen_number(double float_val, int kind) { switch (kind) { case 'x': _true.x += float_val; float_val = _true.x - _false.x; break; case 'y': _true.y += float_val; float_val = _true.y - _false.y; break; case 'X': _true.x = float_val; break; case 'Y': _true.y = float_val; break; } // 30.Jul.2003 - Avoid rounding differences between platforms with the // extra 0.00001. int big_val = (int)floor(float_val * _f_precision + 0.50001); gen_rational(big_val, _precision); float_val = big_val / _f_precision; switch (kind) { case 'x': _false.x += float_val; break; case 'y': _false.y += float_val; break; case 'X': _false.x = float_val; break; case 'Y': _false.y = float_val; break; } } void Type1CharstringGen::gen_command(int command) { if (command >= Charstring::cEscapeDelta) { _ncs.append((char)Charstring::cEscape); _ncs.append((char)(command - Charstring::cEscapeDelta)); if (command != Charstring::cSbw) _state = S_GEN; } else { _ncs.append((char)command); if (command > Charstring::cVmoveto && command != Charstring::cHsbw) _state = S_GEN; } } bool Type1CharstringGen::gen_stem3_stack(CharstringInterp &interp) { // special handling to ensure rounding doesn't generate an invalid stem3 // hint if (interp.size() < 6) return false; // sort hints int i0, i1, i2; if (interp.at(0) > interp.at(2)) i0 = 2, i1 = 0; else i0 = 0, i1 = 2; if (interp.at(4) < interp.at(i0)) i2 = i1, i1 = i0, i0 = 4; else if (interp.at(4) < interp.at(i1)) i2 = i1, i1 = 4; else i2 = 4; // check constraints. count "almost equal" as equal double stemw0 = interp.at(i0+1), stemw2 = interp.at(i2+1); if ((int)(1024*(stemw0 - stemw2) + .5) != 0) return false; double c0 = interp.at(i0) + interp.at(i0+1)/2; double c1 = interp.at(i1) + interp.at(i1+1)/2; double c2 = interp.at(i2) + interp.at(i2+1)/2; if ((int)(1024*((c1 - c0) - (c2 - c1)) + .5) != 0) return false; // if all constraints are satisfied now, make sure they are also satisfied // after rounding int big_v0 = (int)floor(interp.at(i0) * _f_precision + 0.50001); int big_v2 = (int)floor(interp.at(i2) * _f_precision + 0.50001); int big_stemw0 = (int)floor(stemw0 * _f_precision + 0.50001); int big_stemw1 = (int)floor(interp.at(i1+1) * _f_precision + 0.50001); int big_v1_times2 = big_v0 + big_v2 + big_stemw0 - big_stemw1; gen_rational(big_v0, _precision); gen_rational(big_stemw0, _precision); if (big_v1_times2 % 2) gen_rational(big_v1_times2, 2 * _precision); else gen_rational(big_v1_times2 / 2, _precision); gen_rational(big_stemw1, _precision); gen_rational(big_v2, _precision); gen_rational(big_stemw0, _precision); interp.clear(); return true; } void Type1CharstringGen::gen_stack(CharstringInterp &interp, int for_cmd) { const char *str = ((unsigned)for_cmd <= Charstring::cLastCommand ? command_desc[for_cmd] : (const char *)0); if ((for_cmd == Charstring::cHstem3 || for_cmd == Charstring::cVstem3) && gen_stem3_stack(interp)) return; int i; for (i = 0; str && *str && i < interp.size(); i++, str++) gen_number(interp.at(i), *str); for (; i < interp.size(); i++) gen_number(interp.at(i)); interp.clear(); } void Type1CharstringGen::gen_moveto(const Point &p, bool closepath, bool always) { // make sure we generate some moveto on the first command Point d = p - _true; int big_dx = (int)floor(d.x * _f_precision + 0.50001); int big_dy = (int)floor(d.y * _f_precision + 0.50001); if (big_dx == 0 && big_dy == 0 && _state != S_INITIAL && !always) /* do nothing */; else { if (closepath) gen_command(Charstring::cClosepath); if (big_dy == 0) { gen_number(d.x, 'x'); gen_command(Charstring::cHmoveto); } else if (big_dx == 0) { gen_number(d.y, 'y'); gen_command(Charstring::cVmoveto); } else { gen_number(d.x, 'x'); gen_number(d.y, 'y'); gen_command(Charstring::cRmoveto); } } _true = p; } void Type1CharstringGen::append_charstring(const String &s) { _ncs << s; } Type1Charstring * Type1CharstringGen::output() { return new Type1Charstring(take_string()); } void Type1CharstringGen::output(Type1Charstring &cs) { cs.assign(take_string()); } String Type1CharstringGen::callsubr_string(int subr) { Type1CharstringGen csg; csg.gen_number(subr); csg.gen_command(Charstring::cCallsubr); return csg._ncs.take_string(); } /***** * Type1CharstringGenInterp **/ Type1CharstringGenInterp::Type1CharstringGenInterp(int precision) : _csgen(precision), _hint_csgen(precision), _direct_hr(false), _hr_storage(0), _max_flex_height(0), _had_flex(false), _had_bad_flex(false), _had_hr(false) { } void Type1CharstringGenInterp::set_hint_replacement_storage(Type1Font *font) { _hr_storage = font; _hr_firstsubr = font->nsubrs(); } // generating charstring commands inline void Type1CharstringGenInterp::gen_number(double n, int what) { _csgen.gen_number(n, what); } inline void Type1CharstringGenInterp::gen_command(int what) { _csgen.gen_command(what); } void Type1CharstringGenInterp::gen_sbw(bool hints_follow) { if (!hints_follow && nhints()) act_hintmask(Cs::cHintmask, 0, nhints()); else if (left_sidebearing().y == 0 && _width.y == 0) { gen_number(left_sidebearing().x, 'X'); gen_number(_width.x); gen_command(Cs::cHsbw); } else { gen_number(left_sidebearing().x, 'X'); gen_number(left_sidebearing().y, 'Y'); gen_number(_width.x); gen_number(_width.y); gen_command(Cs::cSbw); } _state = S_CLOSED; } void Type1CharstringGenInterp::act_width(int, const Point &p) { _width = p; } void Type1CharstringGenInterp::act_seac(int, double asb, double adx, double ady, int bchar, int achar) { if (_state == S_INITIAL) gen_sbw(false); gen_number(asb); gen_number(adx); gen_number(ady); gen_number(bchar); gen_number(achar); gen_command(Cs::cSeac); _state = S_SEAC; } void Type1CharstringGenInterp::swap_stem_hints() { _stem_pos.clear(); _stem_width.clear(); _stem_hstem.clear(); _in_hr = true; } void Type1CharstringGenInterp::act_hstem(int, double pos, double width) { if (_state != S_INITIAL && !_in_hr) swap_stem_hints(); _stem_pos.push_back(pos); _stem_width.push_back(width); _stem_hstem.push_back(1); } void Type1CharstringGenInterp::act_vstem(int, double pos, double width) { if (_state != S_INITIAL && !_in_hr) swap_stem_hints(); _stem_pos.push_back(pos); _stem_width.push_back(width); _stem_hstem.push_back(0); } String Type1CharstringGenInterp::gen_hints(const unsigned char *data, int nhints) const { _hint_csgen.clear(); unsigned char mask = 0x80; for (int i = 0; i < nhints; i++) { if (*data & mask) { double offset = (_stem_hstem[i] ? left_sidebearing().y : left_sidebearing().x); _hint_csgen.gen_number(_stem_pos[i] - offset); _hint_csgen.gen_number(_stem_width[i]); _hint_csgen.gen_command(_stem_hstem[i] ? Cs::cHstem : Cs::cVstem); } if ((mask >>= 1) == 0) data++, mask = 0x80; } return _hint_csgen.take_string(); } void Type1CharstringGenInterp::act_hintmask(int cmd, const unsigned char *data, int nhints) { if (cmd == Cs::cCntrmask || nhints > Type1CharstringGenInterp::nhints()) return; String data_holder; if (!data) { data_holder = String::make_fill('\377', ((nhints - 1) >> 3) + 1); data = data_holder.udata(); } String hints = gen_hints(data, nhints); _in_hr = false; if (_state == S_INITIAL || _direct_hr) { _last_hints = hints; if (_state == S_INITIAL) gen_sbw(true); _csgen.append_charstring(hints); } else if (_hr_storage && hints != _last_hints) { _last_hints = hints; hints += (char)(Cs::cReturn); int subrno = -1, nsubrs = _hr_storage->nsubrs(); for (int i = _hr_firstsubr; i < nsubrs; i++) if (Type1Subr *s = _hr_storage->subr_x(i)) if (s->t1cs() == hints) { subrno = i; break; } if (subrno < 0 && _hr_storage->set_subr(nsubrs, Type1Charstring(hints))) subrno = nsubrs; if (subrno >= 0) { _had_hr = true; _csgen.gen_number(subrno); _csgen.gen_number(4); _csgen.gen_command(Cs::cCallsubr); } } } void Type1CharstringGenInterp::act_line(int cmd, const Point &a, const Point &b) { if (_state == S_INITIAL) gen_sbw(false); else if (_in_hr) act_hintmask(cmd, 0, nhints()); _csgen.gen_moveto(a, _state == S_OPEN, false); _state = S_OPEN; if (a.x == b.x) { gen_number(b.y - a.y, 'y'); gen_command(Cs::cVlineto); } else if (a.y == b.y) { gen_number(b.x - a.x, 'x'); gen_command(Cs::cHlineto); } else { gen_number(b.x - a.x, 'x'); gen_number(b.y - a.y, 'y'); gen_command(Cs::cRlineto); } } void Type1CharstringGenInterp::act_curve(int cmd, const Point &a, const Point &b, const Point &c, const Point &d) { if (_state == S_INITIAL) gen_sbw(false); else if (_in_hr) act_hintmask(cmd, 0, nhints()); _csgen.gen_moveto(a, _state == S_OPEN, false); _state = S_OPEN; if (b.y == a.y && d.x == c.x) { gen_number(b.x - a.x, 'x'); gen_number(c.x - b.x, 'x'); gen_number(c.y - b.y, 'y'); gen_number(d.y - c.y, 'y'); gen_command(Cs::cHvcurveto); } else if (b.x == a.x && d.y == c.y) { gen_number(b.y - a.y, 'y'); gen_number(c.x - a.x, 'x'); gen_number(c.y - b.y, 'y'); gen_number(d.x - c.x, 'x'); gen_command(Cs::cVhcurveto); } else { gen_number(b.x - a.x, 'x'); gen_number(b.y - a.y, 'y'); gen_number(c.x - b.x, 'x'); gen_number(c.y - b.y, 'y'); gen_number(d.x - c.x, 'x'); gen_number(d.y - c.y, 'y'); gen_command(Cs::cRrcurveto); } } void Type1CharstringGenInterp::act_flex(int cmd, const Point &p0, const Point &p1, const Point &p2, const Point &p3_4, const Point &p5, const Point &p6, const Point &p7, double flex_depth) { if (_state == S_INITIAL) gen_sbw(false); else if (_in_hr) act_hintmask(cmd, 0, nhints()); _csgen.gen_moveto(p0, _state == S_OPEN, false); _state = S_OPEN; // 1. Outer endpoints must have same x (or y) coordinate bool v_ok = (p0.x == p7.x); bool h_ok = (p0.y == p7.y); // 2. Join point and its neighboring controls must be at an extreme if (v_ok && p2.x == p3_4.x && p3_4.x == p5.x) { double distance = fabs(p3_4.x - p0.x); int sign = (p3_4.x < p0.x ? -1 : 1); if (sign * (p1.x - p0.x) < 0 || sign * (p1.x - p0.x) > distance || sign * (p6.x - p0.x) < 0 || sign * (p6.x - p0.x) > distance) v_ok = false; } else v_ok = false; if (h_ok && p2.y == p3_4.y && p3_4.y == p5.y) { double distance = fabs(p3_4.y - p0.y); int sign = (p3_4.y < p0.y ? -1 : 1); if (sign * (p1.y - p0.y) < 0 || sign * (p1.y - p0.y) > distance || sign * (p6.y - p0.y) < 0 || sign * (p6.y - p0.y) > distance) h_ok = false; } else h_ok = false; // 3. Flex height <= 20 if (v_ok && fabs(p3_4.x - p0.x) > 20) v_ok = false; if (h_ok && fabs(p3_4.y - p0.y) > 20) h_ok = false; // generate flex commands if (v_ok || h_ok) { _had_flex = true; Point p_reference = (h_ok ? Point(p3_4.x, p0.y) : Point(p0.x, p3_4.y)); _csgen.gen_number(1); _csgen.gen_command(Cs::cCallsubr); _csgen.gen_moveto(p_reference, false, true); _csgen.gen_number(2); _csgen.gen_command(Cs::cCallsubr); _csgen.gen_moveto(p1, false, true); _csgen.gen_number(2); _csgen.gen_command(Cs::cCallsubr); _csgen.gen_moveto(p2, false, true); _csgen.gen_number(2); _csgen.gen_command(Cs::cCallsubr); _csgen.gen_moveto(p3_4, false, true); _csgen.gen_number(2); _csgen.gen_command(Cs::cCallsubr); _csgen.gen_moveto(p5, false, true); _csgen.gen_number(2); _csgen.gen_command(Cs::cCallsubr); _csgen.gen_moveto(p6, false, true); _csgen.gen_number(2); _csgen.gen_command(Cs::cCallsubr); _csgen.gen_moveto(p7, false, true); _csgen.gen_number(2); _csgen.gen_command(Cs::cCallsubr); _csgen.gen_number(flex_depth); _csgen.gen_number(p7.x, 'X'); _csgen.gen_number(p7.y, 'Y'); _csgen.gen_number(0); _csgen.gen_command(Cs::cCallsubr); double flex_height = fabs(h_ok ? p3_4.y - p0.y : p3_4.x - p0.x); if (flex_height > _max_flex_height) _max_flex_height = flex_height; } else { _had_bad_flex = true; act_curve(cmd, p0, p1, p2, p3_4); act_curve(cmd, p3_4, p5, p6, p7); } } void Type1CharstringGenInterp::act_closepath(int cmd) { if (_in_hr) act_hintmask(cmd, 0, nhints()); gen_command(Cs::cClosepath); _state = S_CLOSED; } void Type1CharstringGenInterp::intermediate_output(Type1Charstring &out) { _csgen.output(out); _state = S_INITIAL; act_hintmask(Cs::cEndchar, 0, nhints()); } void Type1CharstringGenInterp::run(const CharstringContext &g, Type1Charstring &out) { _width = Point(0, 0); _csgen.clear(); swap_stem_hints(); _state = S_INITIAL; _in_hr = false; CharstringInterp::interpret(g); if (_state == S_INITIAL) gen_sbw(false); else if (_in_hr) act_hintmask(Cs::cEndchar, 0, nhints()); if (_state != S_SEAC) _csgen.gen_command(Cs::cEndchar); _csgen.output(out); } } lcdf-typetools-2.108/libefont/t1font.cc0000644000175000017500000006534313423375327014765 00000000000000// -*- related-file-name: "../include/efont/t1font.hh" -*- /* t1font.{cc,hh} -- Type 1 font * * Copyright (c) 1998-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include namespace Efont { static PermString::Initializer initializer; static PermString lenIV_str = "lenIV"; static PermString FontInfo_str = "FontInfo"; Type1Font::Type1Font(PermString name) : CharstringProgram(1000), _cached_defs(false), _built(true), _font_name(name), _glyph_map(-1), _encoding(0), _cached_mmspace(0), _mmspace(0), _synthetic_item(0) { _dict = new HashMap[dLast]; for (int i = 0; i < dLast; i++) { _index[i] = -1; _dict_deltas[i] = 0; _dict[i].set_default_value((Type1Definition *)0); } } Type1Font::Type1Font(Type1Reader &reader) : CharstringProgram(1000), _cached_defs(false), _built(false), _glyph_map(-1), _encoding(0), _cached_mmspace(0), _mmspace(0), _synthetic_item(0) { _dict = new HashMap[dLast]; for (int i = 0; i < dLast; i++) { _index[i] = -1; _dict_deltas[i] = 0; _dict[i].set_default_value((Type1Definition *)0); } read(reader); } Type1Font::~Type1Font() { delete[] _dict; for (int i = 0; i < _items.size(); i++) delete _items[i]; delete _mmspace; for (int i = 0; i < _subrs.size(); i++) delete _subrs[i]; if (!_synthetic_item) for (int i = 0; i < _glyphs.size(); i++) delete _glyphs[i]; } void Type1Font::set_item(int i, Type1Item *it) { delete _items[i]; _items[i] = it; } static const char * const dict_starters[] = { "0 dict begin", "/FontInfo 0 dict dup begin", "dup /Private 0 dict dup begin", "/Blend 0 dict dup begin", 0, 0 }; void Type1Font::add_definition(int dict, Type1Definition *t1d) { if (_index[dict] < 0) { if (_built && dict_starters[dict]) add_item(new Type1CopyItem(dict_starters[dict])); _index[dict] = _items.size(); } add_item(t1d); set_dict(dict, t1d->name(), t1d); } void Type1Font::add_type1_encoding(Type1Encoding *e) { if (_encoding) { for (Type1Item** t1i = _items.begin(); t1i < _items.end(); t1i++) if (*t1i == _encoding) { delete _encoding; *t1i = _encoding = e; return; } } _encoding = e; add_item(e); } void Type1Font::add_glyph(Type1Subr *s) { int &g = _glyph_map.find_force(s->name(), _glyphs.size()); if (g == _glyphs.size()) _glyphs.push_back(s); else { delete _glyphs[g]; _glyphs[g] = s; } } int Type1Font::read(Type1Reader &reader) { Dict cur_dict = dFont; int eexec_state = 0; bool have_subrs = false; bool have_charstrings = false; int lenIV = 4; Type1SubrGroupItem *cur_group = 0; int cur_group_count = 0; StringAccum accum; while (reader.next_line(accum)) { // check for NULL STRING int x_length = accum.length(); if (!x_length) continue; const char *x = accum.c_str(); // ensure we don't run off the string // check for CHARSTRINGS if (reader.was_charstring()) { Type1Subr *fcs = Type1Subr::make(x, x_length, reader.charstring_start(), reader.charstring_length(), lenIV); if (fcs->is_subr()) { if (fcs->subrno() >= _subrs.size()) _subrs.resize(fcs->subrno() + 30, (Type1Subr *)0); if (_subrs[fcs->subrno()]) // hybrid font program delete _subrs[fcs->subrno()]; _subrs[fcs->subrno()] = fcs; if (!have_subrs && _items.size()) { if (Type1CopyItem *item = _items.back()->cast_copy()) { cur_group = new Type1SubrGroupItem (this, true, item->value()); cur_group_count = 0; _items.back() = cur_group; delete item; } have_subrs = true; } } else { add_glyph(fcs); if (!have_charstrings && _items.size()) { if (Type1CopyItem *item = _items.back()->cast_copy()) { cur_group = new Type1SubrGroupItem (this, false, item->value()); cur_group_count = 0; _items.back() = cur_group; delete item; } have_charstrings = true; } } accum.clear(); continue; } // check for COMMENTS if (x[0] == '%') { add_item(new Type1CopyItem(accum.take_string())); continue; } // check for CHARSTRING START // 5/29/1999: beware of charstring start-like things that don't have // `readstring' in them! if (!_charstring_definer && strstr(x, "string currentfile") != 0 && strstr(x, "readstring") != 0) { const char *sb = x; while (*sb && *sb != '/') sb++; const char *se = sb + 1; while (*sb && *se && *se != ' ' && *se != '{') se++; if (*sb && *se) { _charstring_definer = permprintf(" %*s ", se - sb - 1, sb + 1); reader.set_charstring_definer(_charstring_definer); add_item(new Type1CopyItem(accum.take_string())); continue; } } // check for ENCODING if (!_encoding && strncmp(x, "/Encoding ", 10) == 0) { read_encoding(reader, x + 10); accum.clear(); continue; } // check for a DEFINITION if (x[0] == '/') { definition_succeed: Type1Definition *t1d = Type1Definition::make(accum, &reader); if (!t1d) goto definition_fail; if (t1d->name() == lenIV_str) t1d->value_int(lenIV); add_definition(cur_dict, t1d); accum.clear(); continue; } else if (x[0] == ' ') { const char *y; for (y = x; y[0] == ' '; y++) ; if (y[0] == '/') goto definition_succeed; } definition_fail: // check for ZEROS special case if (eexec_state == 2) { // In eexec_state 2 (right after turning off eexec), the opening // part of the string will have some 0 bytes followed by '0's. // Change the 0 bytes into textual '0's. int zeros = 0; while (x[zeros] == 0 && x_length > 0) zeros++, x_length--; add_item(new Type1CopyItem(String::make_fill('0', zeros * 2 + x_length))); eexec_state = 3; accum.clear(); continue; } // check for MODIFIED FONT if (eexec_state == 1 && strstr(x, "FontDirectory") != 0 && read_synthetic_font(reader, x, accum)) { accum.clear(); continue; } // check for END-OF-CHARSTRING-GROUP TEXT if (cur_group) { if (cur_group_count == 0 || ((strstr(x, "end") != 0 || strstr(x, "put") != 0) && strchr(x, '/') == 0)) { cur_group->add_end_text(x); cur_group_count++; accum.clear(); continue; } cur_group = 0; } // add COPY ITEM String s = accum.take_string(); add_item(new Type1CopyItem(s)); x = s.data(); if (eexec_state == 0 && strncmp(x, "currentfile eexec", 17) == 0 && (isspace((unsigned char) x[17]) || !x[17])) { // allow arbitrary whitespace after "currentfile eexec". // note: strlen("currentfile eexec") == 17 for (x += 17; isspace((unsigned char) *x); x++) /* nada */; reader.switch_eexec(true, (unsigned char *)x, (s.data() + s.length()) - x); set_item(nitems() - 1, new Type1EexecItem(true)); eexec_state = 1; } else if (eexec_state == 1 && strstr(x, "currentfile closefile") != 0) { reader.switch_eexec(false, 0, 0); add_item(new Type1EexecItem(false)); eexec_state = 2; } else if (strstr(x, "begin") != 0) { // 30.Sep.2002: NuevaMM's BlendFontInfo dict starts with a simple // "/FontInfo ... begin" inside a "/Blend ... begin". Dict was_dict = cur_dict; if (strstr(x, "/Private") != 0) cur_dict = dPrivate; else if (strstr(x, "/FontInfo") != 0) cur_dict = dFontInfo; else cur_dict = dFont; if (strstr(x, "/Blend") != 0) cur_dict = (Dict)(cur_dict + dBlend); else if (was_dict == dBlend && cur_dict == dFontInfo) cur_dict = (Dict)(cur_dict + dBlend); } else if (cur_dict == dFontInfo && strstr(x, "end") != 0) cur_dict = dFont; } // set dictionary deltas for (int i = dFI; i < dLast; i++) _dict_deltas[i] = get_dict_size(i) - _dict[i].size(); // borrow glyphs and glyph map from _synthetic_item if (!_glyphs.size() && _synthetic_item) { _glyphs = _synthetic_item->included_font()->_glyphs; _glyph_map = _synthetic_item->included_font()->_glyph_map; } return (ok() ? 0 : -1); } bool Type1Font::ok() const { return font_name() && _glyphs.size() > 0; } static char *skip_comment_space(char *s) { while (1) { if (isspace((unsigned char) *s)) ++s; else if (*s == '%') { for (++s; *s != '\r' && *s != '\n' && *s != '\0'; ++s) /* nada */; } else return s; } } void Type1Font::read_encoding(Type1Reader &reader, const char *first_line) { while (isspace((unsigned char) *first_line)) first_line++; if (strncmp(first_line, "StandardEncoding", 16) == 0) { add_type1_encoding(Type1Encoding::standard_encoding()); return; } add_type1_encoding(new Type1Encoding); bool got_any = false; StringAccum accum; while (reader.next_line(accum)) { // check for NULL STRING if (!accum.length()) continue; accum.append('\0'); // ensure we don't run off the string char *pos = accum.data(); // skip to first `dup' token if (!got_any) { if (!(pos = strstr(pos, "dup"))) { pos = accum.data(); goto check_done; } } // parse as many `dup INDEX */CHARNAME put' as there are in the line while (1) { // skip spaces, look for `dup ' while (isspace((unsigned char) pos[0])) ++pos; if (pos[0] == '%') pos = skip_comment_space(pos); if (pos[0] != 'd' || pos[1] != 'u' || pos[2] != 'p' || !isspace((unsigned char) pos[3])) break; // look for `INDEX */' char *scan; int char_value = strtol(pos + 4, &scan, 10); if (scan[0] == '#' && char_value > 0 && char_value < 37 && isalnum((unsigned char) scan[1])) char_value = strtol(scan + 1, &scan, char_value); while (isspace((unsigned char) scan[0])) scan++; if (char_value < 0 || char_value >= 256 || scan[0] != '/') break; // look for `CHARNAME put' scan++; char *name_pos = scan; while (!isspace((unsigned char) scan[0]) && scan[0] != '\0') ++scan; char *name_end = scan; while (isspace((unsigned char) scan[0])) ++scan; if (scan[0] != 'p' || scan[1] != 'u' || scan[2] != 't') break; _encoding->put(char_value, PermString(name_pos, name_end - name_pos)); got_any = true; pos = scan + 3; } check_done: // check for end of encoding section // if not over, add COPY ITEM for leftovers we didn't parse if ((strstr(pos, "readonly") != 0 || strstr(pos, "def") != 0) && (got_any || strstr(pos, "for") == 0)) { _encoding->set_definer(String(pos)); return; } else if (got_any && *pos) add_item(new Type1CopyItem(String(pos))); accum.clear(); } } static bool read_synthetic_string(Type1Reader &reader, StringAccum &wrong_accum, const char *format, int *value) { StringAccum accum; if (!reader.next_line(accum)) return false; wrong_accum << accum; accum.append('\0'); // ensure we don't run off the string int n = 0; if (value) sscanf(accum.data(), format, value, &n); else sscanf(accum.data(), format, &n); return (n != 0 && (isspace((unsigned char) accum[n]) || accum[n] == '\0')); } bool Type1Font::read_synthetic_font(Type1Reader &reader, const char *first_line, StringAccum &wrong_accum) { // read font name PermString font_name; { char *x = new char[strlen(first_line) + 1]; int n = 0; sscanf(first_line, "FontDirectory /%[^] \t\r\n[{}/] known {%n", x, &n); if (n && (isspace((unsigned char) first_line[n]) || first_line[n] == 0)) font_name = x; delete[] x; if (!font_name) return false; } // check UniqueID int unique_id; { StringAccum accum; if (!reader.next_line(accum)) return false; wrong_accum << accum; accum.c_str(); // ensure we don't run off the string const char *y = accum.data(); if (*y != '/' || strncmp(y + 1, font_name.c_str(), font_name.length()) != 0) return false; int n = 0; sscanf(y + font_name.length() + 1, " findfont%n", &n); y = strstr(y, "/UniqueID get "); if (n == 0 || y == 0) return false; n = 0; sscanf(y + 14, "%d%n", &unique_id, &n); if (n == 0) return false; } // check lines that say how much text int multiplier; if (!read_synthetic_string(reader, wrong_accum, "save userdict /fbufstr %d string put%n", &multiplier)) return false; int multiplicand; if (!read_synthetic_string(reader, wrong_accum, "%d {currentfile fbufstr readstring { pop } { clear currentfile%n", &multiplicand)) return false; if (!read_synthetic_string(reader, wrong_accum, "closefile /fontdownload /unexpectedEOF /.error cvx exec } ifelse } repeat%n", 0)) return false; int extra; if (!read_synthetic_string(reader, wrong_accum, "currentfile %d string readstring { pop } { clear currentfile%n", &extra)) return false; if (!read_synthetic_string(reader, wrong_accum, "closefile /fontdownload /unexpectedEOF /.error cvx exec } ifelse%n", 0)) return false; if (!read_synthetic_string(reader, wrong_accum, "restore } if } if%n", 0)) return false; Type1SubsetReader subreader(&reader, multiplier*multiplicand + extra); Type1Font *synthetic = new Type1Font(subreader); if (!synthetic->ok()) delete synthetic; else { _synthetic_item = new Type1IncludedFont(synthetic, unique_id); add_item(_synthetic_item); } return true; } void Type1Font::undo_synthetic() { // A synthetic font doesn't share arbitrary code with its base font; it // shares just the CharStrings dictionary, according to Adobe Type 1 Font // Format. We take advantage of this. if (!_synthetic_item) return; int mod_ii; for (mod_ii = nitems() - 1; mod_ii >= 0; mod_ii--) if (_items[mod_ii] == _synthetic_item) break; if (mod_ii < 0) return; // remove synthetic item and the reference to the included font _items[mod_ii] = new Type1NullItem; if (Type1CopyItem *copy = _items[mod_ii+1]->cast_copy()) if (copy->value().find_left("findfont") >= 0) { delete copy; _items[mod_ii+1] = new Type1NullItem; } Type1Font *f = _synthetic_item->included_font(); // its glyphs are already stored in our _glyphs array // copy SubrGroupItem from `f' into `this' Type1SubrGroupItem *oth_subrs = 0, *oth_glyphs = 0; for (int i = 0; i < f->nitems(); i++) if (Type1SubrGroupItem *subr_grp = f->_items[i]->cast_subr_group()) { if (subr_grp->is_subrs()) oth_subrs = subr_grp; else oth_glyphs = subr_grp; } assert(oth_glyphs != 0); for (int i = nitems() - 1; i >= 0; i--) if (Type1SubrGroupItem *subr_grp = _items[i]->cast_subr_group()) { assert(subr_grp->is_subrs()); if (oth_subrs) subr_grp->set_end_text(oth_subrs->end_text()); shift_indices(i + 1, 1); Type1SubrGroupItem *nsubr = new Type1SubrGroupItem(*oth_glyphs, this); _items[i + 1] = nsubr; break; } // delete included font f->_glyphs.clear(); // don't delete glyphs; we've stolen them delete _synthetic_item; _synthetic_item = 0; } Type1Charstring * Type1Font::subr(int e) const { if (e >= 0 && e < _subrs.size() && _subrs[e]) return &_subrs[e]->t1cs(); else return 0; } PermString Type1Font::glyph_name(int i) const { if (i >= 0 && i < _glyphs.size() && _glyphs[i]) return _glyphs[i]->name(); else return PermString(); } Type1Charstring * Type1Font::glyph(int i) const { if (i >= 0 && i < _glyphs.size() && _glyphs[i]) return &_glyphs[i]->t1cs(); else return 0; } Type1Charstring * Type1Font::glyph(PermString name) const { int i = _glyph_map[name]; if (i >= 0) return &_glyphs[i]->t1cs(); else return 0; } bool Type1Font::set_subr(int e, const Type1Charstring &t1cs, PermString definer) { if (e < 0) return false; if (e >= _subrs.size()) _subrs.resize(e + 1, (Type1Subr *)0); if (!definer) { Type1Subr *pattern_subr = _subrs[e]; for (int i = 0; i < _subrs.size() && !pattern_subr; i++) pattern_subr = _subrs[i]; if (!pattern_subr) return false; definer = pattern_subr->definer(); } delete _subrs[e]; _subrs[e] = Type1Subr::make_subr(e, t1cs, definer); return true; } bool Type1Font::remove_subr(int e) { if (e < 0 || e >= _subrs.size()) return false; delete _subrs[e]; _subrs[e] = 0; return true; } void Type1Font::fill_in_subrs() { while (_subrs.size() && _subrs.back() == 0) _subrs.pop_back(); for (int i = 0; i < _subrs.size(); i++) if (!_subrs[i]) set_subr(i, Type1Charstring(String::make_stable("\013", 1))); } void Type1Font::renumber_subrs(const Vector &renumbering) { Vector old_subrs; old_subrs.swap(_subrs); for (int i = 0; i < old_subrs.size() && i < renumbering.size(); i++) { int r = renumbering[i]; Type1Subr *s = old_subrs[i]; if (r >= 0 && s) set_subr(r, s->t1cs(), s->definer()); else delete s; } for (int i = renumbering.size(); i < old_subrs.size(); i++) delete old_subrs[i]; } void Type1Font::shift_indices(int move_index, int delta) { if (delta > 0) { _items.resize(_items.size() + delta, (Type1Item *)0); memmove(&_items[move_index + delta], &_items[move_index], sizeof(Type1Item *) * (_items.size() - move_index - delta)); for (int i = dFont; i < dLast; i++) if (_index[i] > move_index) _index[i] += delta; } else { memmove(&_items[move_index], &_items[move_index - delta], sizeof(Type1Item *) * (_items.size() - (move_index - delta))); _items.resize(_items.size() + delta); for (int i = dFont; i < dLast; i++) if (_index[i] >= move_index) { if (_index[i] < move_index - delta) _index[i] = move_index; else _index[i] += delta; } } } Type1Definition * Type1Font::ensure(Dict dict, PermString name) { assert(_index[dict] >= 0); Type1Definition *def = _dict[dict][name]; if (!def) { def = new Type1Definition(name, 0, "def"); int move_index = _index[dict]; shift_indices(move_index, 1); _items[move_index] = def; set_dict(dict, name, def); } return def; } void Type1Font::add_header_comment(const String &comment) { int i; for (i = 0; i < _items.size(); i++) { Type1CopyItem *copy = _items[i]->cast_copy(); if (!copy || copy->value()[0] != '%') break; } shift_indices(i, 1); _items[i] = new Type1CopyItem(comment); } Type1Item * Type1Font::dict_size_item(int d) const { switch (d) { case dF: if (_built && _index[d] > 0) return _items[_index[d] - 1]; break; case dFI: case dP: case dB: if (_index[d] > 0) return _items[_index[d] - 1]; break; case dBFI: if (Type1Item *t1i = b_dict("FontInfo")) return t1i; else if (_index[dBFI] > 0) return _items[_index[dBFI] - 1]; break; case dBP: if (Type1Item *t1i = b_dict("Private")) return t1i; else if (_index[dBP] > 0) return _items[_index[dBP] - 1]; break; } return 0; } int Type1Font::get_dict_size(int d) const { Type1Item *item = dict_size_item(d); if (!item) /* nada */; else if (Type1Definition *t1d = item->cast_definition()) { int num; if (strstr(t1d->definer().c_str(), "dict") && t1d->value_int(num)) return num; } else if (Type1CopyItem *copy = item->cast_copy()) { String value = copy->value(); int pos = value.find_left(" dict"); if (pos >= 1 && isdigit((unsigned char) value[pos - 1])) { while (pos >= 1 && isdigit((unsigned char) value[pos - 1])) pos--; return strtol(value.data() + pos, 0, 10); } } return -1; } void Type1Font::set_dict_size(int d, int size) { Type1Item *item = dict_size_item(d); if (!item) return; if (Type1Definition *t1d = item->cast_definition()) { int num; if (strstr(t1d->definer().c_str(), "dict") && t1d->value_int(num)) t1d->set_int(size); } else if (Type1CopyItem *copy = item->cast_copy()) { String value = copy->value(); int pos = value.find_left(" dict"); if (pos >= 1 && isdigit((unsigned char) value[pos - 1])) { int numpos = pos - 1; while (numpos >= 1 && isdigit((unsigned char) value[numpos - 1])) numpos--; StringAccum accum; accum << value.substring(0, numpos) << size << value.substring(pos); copy->set_value(accum.take_string()); } } } void Type1Font::write(Type1Writer &w) { Type1Definition *lenIV_def = p_dict("lenIV"); int lenIV = 4; if (lenIV_def) lenIV_def->value_int(lenIV); w.set_charstring_start(_charstring_definer); w.set_lenIV(lenIV); // change dict sizes for (int i = dF; i < dLast; i++) set_dict_size(i, _dict[i].size() + _dict_deltas[i]); // XXX what if dict had nothing, but now has something? for (int i = 0; i < _items.size(); i++) _items[i]->gen(w); w.flush(); } void Type1Font::cache_defs() const { Type1Definition *t1d = dict("FontName"); if (t1d) t1d->value_name(_font_name); _cached_defs = true; } MultipleMasterSpace * Type1Font::mmspace() const { if (!_cached_mmspace) create_mmspace(); return _mmspace; } MultipleMasterSpace * Type1Font::create_mmspace(ErrorHandler *errh) const { if (_cached_mmspace) return _mmspace; _cached_mmspace = 1; Type1Definition *t1d; Vector< Vector > master_positions; t1d = fi_dict("BlendDesignPositions"); if (!t1d || !t1d->value_numvec_vec(master_positions)) return 0; int nmasters = master_positions.size(); if (nmasters <= 0) { errh->error("bad BlendDesignPositions"); return 0; } int naxes = master_positions[0].size(); _mmspace = new MultipleMasterSpace(font_name(), naxes, nmasters); _mmspace->set_master_positions(master_positions); Vector< Vector > normalize_in, normalize_out; t1d = fi_dict("BlendDesignMap"); if (t1d && t1d->value_normalize(normalize_in, normalize_out)) _mmspace->set_normalize(normalize_in, normalize_out); Vector axis_types; t1d = fi_dict("BlendAxisTypes"); if (t1d && t1d->value_namevec(axis_types) && axis_types.size() == naxes) for (int a = 0; a < naxes; a++) _mmspace->set_axis_type(a, axis_types[a]); int ndv, cdv; Type1Charstring *cs; t1d = p_dict("NDV"); if (t1d && t1d->value_int(ndv) && (cs = subr(ndv))) _mmspace->set_ndv(*cs); t1d = p_dict("CDV"); if (t1d && t1d->value_int(cdv) && (cs = subr(cdv))) _mmspace->set_cdv(*cs); Vector design_vector; t1d = dict("DesignVector"); if (t1d && t1d->value_numvec(design_vector)) _mmspace->set_design_vector(design_vector); Vector weight_vector; t1d = dict("WeightVector"); if (t1d && t1d->value_numvec(weight_vector)) _mmspace->set_weight_vector(weight_vector); if (!_mmspace->check(errh)) { delete _mmspace; _mmspace = 0; } return _mmspace; } void Type1Font::uncache_defs() { _cached_defs = false; } void Type1Font::font_matrix(double matrix[6]) const { Vector t1d_matrix; Type1Definition *t1d = dict("FontMatrix"); if (t1d && t1d->value_numvec(t1d_matrix) && t1d_matrix.size() == 6) memcpy(&matrix[0], &t1d_matrix[0], sizeof(double) * 6); else { matrix[0] = matrix[3] = 0.001; matrix[1] = matrix[2] = matrix[4] = matrix[5] = 0; } } } lcdf-typetools-2.108/libefont/afmw.cc0000644000175000017500000001301713423375327014473 00000000000000// -*- related-file-name: "../include/efont/afmw.hh" -*- /* afmw.{cc,hh} -- Adobe Font Metrics writing * * Copyright (c) 1998-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include /* for KNOWN() */ namespace Efont { AfmWriter::AfmWriter(Metrics *m, FILE *f) : _m(m), _afm_xt((AfmMetricsXt *)m->find_xt("AFM")), _f(f) { } void AfmWriter::write(Metrics *m, FILE *f) { AfmWriter w(m, f); w.write(); } void AfmWriter::write() { _m->pair_program()->unreverse(); _m->pair_program()->optimize(); fprintf(_f, "StartFontMetrics 4.1\n"); if (_afm_xt) for (int i = 0; i < _afm_xt->opening_comments.size(); i++) fprintf(_f, "Comment %s\n", _afm_xt->opening_comments[i].c_str()); write_prologue(); fprintf(_f, "StartCharMetrics %d\n", _m->nglyphs()); GlyphIndex gi; for (int i = 0; i < 256; i++) //FIXME if ((gi = _m->find_code(i)) >= 0) write_char_metric_data(gi, i); for (gi = 0; gi < _m->nglyphs(); gi++) if (_m->code(gi) == -1) write_char_metric_data(gi, -1); fprintf(_f, "EndCharMetrics\n"); write_kerns(); fprintf(_f, "EndFontMetrics\n"); } void AfmWriter::write_prologue() const { if (_m->font_name()) fprintf(_f, "FontName %s\n", _m->font_name().c_str()); else fprintf(_f, "FontName No-Font-Name-Given\n"); if (_m->full_name()) fprintf(_f, "FullName %s\n", _m->full_name().c_str()); if (_m->family()) fprintf(_f, "FamilyName %s\n", _m->family().c_str()); if (_m->weight()) fprintf(_f, "Weight %s\n", _m->weight().c_str()); if (KNOWN(fd( fdItalicAngle ))) fprintf(_f, "ItalicAngle %.8g\n", fd( fdItalicAngle )); fprintf(_f, "FontBBox %.8g %.8g %.8g %.8g\n", fd( fdFontBBllx ), fd( fdFontBBlly ), fd( fdFontBBurx ), fd( fdFontBBury )); if (KNOWN(fd( fdUnderlinePosition ))) fprintf(_f, "UnderlinePosition %.8g\n", fd( fdUnderlinePosition )); if (KNOWN(fd( fdUnderlineThickness ))) fprintf(_f, "UnderlineThickness %.8g\n", fd( fdUnderlineThickness )); if (_m->version()) fprintf(_f, "Version %s\n", _m->version().c_str()); if (_afm_xt && _afm_xt->notice) fprintf(_f, "Notice %s\n", _afm_xt->notice.c_str()); if (_afm_xt && _afm_xt->encoding_scheme) fprintf(_f, "EncodingScheme %s\n", _afm_xt->encoding_scheme.c_str()); if (KNOWN(fd( fdCapHeight ))) fprintf(_f, "CapHeight %.8g\n", fd( fdCapHeight )); if (KNOWN(fd( fdXHeight ))) fprintf(_f, "XHeight %.8g\n", fd( fdXHeight )); if (KNOWN(fd( fdAscender ))) fprintf(_f, "Ascender %.8g\n", fd( fdAscender )); if (KNOWN(fd( fdDescender ))) fprintf(_f, "Descender %.8g\n", fd( fdDescender )); if (KNOWN(fd( fdStdHW ))) fprintf(_f, "StdHW %.8g\n", fd( fdStdHW )); if (KNOWN(fd( fdStdVW ))) fprintf(_f, "StdVW %.8g\n", fd( fdStdVW )); } void AfmWriter::write_char_metric_data(GlyphIndex gi, int e) const { if (e >= -1 && e < 256) fprintf(_f, "C %d ;", e); else fprintf(_f, "CH <%04X> ;", e); double w = _m->wd(gi); if (KNOWN(w)) fprintf(_f, " WX %.8g ;", w); else w = 0; fprintf(_f, " N %s ;", _m->name(gi).c_str()); if (KNOWN(_m->lf(gi))) fprintf(_f, " B %.8g %.8g %.8g %.8g ;", _m->lf(gi), _m->bt(gi), _m->rt(gi), _m->tp(gi)); // Run through the ligature/kern program to find ligatures. PairProgram &pairp = *_m->pair_program(); PairOpIndex opi = pairp.find_left(gi); while (opi >= 0) { const PairOp &op = pairp.op(opi); if (op.is_lig()) { if (op.lig_kind() == opLigSimple) fprintf(_f, " L %s %s ;", _m->name( op.right() ).c_str(), _m->name( op.result() ).c_str()); //else //warning("strange ligature combination not supported by AFM"); } opi = op.next_left(); } fputc('\n', _f); } void AfmWriter::write_kerns() const { PairProgram &pairp = *_m->pair_program(); // Damn. First we have to count how many kerning pairs there are. int numkerns = 0; for (PairOpIndex opi = 0; opi < pairp.op_count(); opi++) { const PairOp &op = pairp.op(opi); if (op.is_kern() && _m->kv( op.value() )) numkerns++; } if (numkerns == 0) return; fprintf(_f, "StartKernData\n"); fprintf(_f, "StartKernPairs %d\n", numkerns); for (GlyphIndex gi = 0; gi < _m->nglyphs(); gi++) { PairOpIndex opi = pairp.find_left(gi); while (opi >= 0) { const PairOp &op = pairp.op(opi); if (op.is_kern() && _m->kv( op.value() )) fprintf(_f, "KPX %s %s %.8g\n", _m->name( gi ).c_str(), _m->name( op.right() ).c_str(), _m->kv( op.value() )); opi = op.next_left(); } } fprintf(_f, "EndKernPairs\n"); fprintf(_f, "EndKernData\n"); } } lcdf-typetools-2.108/libefont/ttfcs.cc0000644000175000017500000001753413423375327014674 00000000000000// -*- related-file-name: "../include/efont/ttfcs.hh" -*- /* ttfcs.{cc,hh} -- TrueType "charstring" emulation * * Copyright (c) 2006-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include namespace Efont { typedef OpenType::Glyph Glyph; TrueTypeBoundsCharstringProgram::TrueTypeBoundsCharstringProgram(const OpenType::Font* otf) : CharstringProgram(otf->units_per_em()), _otf(otf), _nglyphs(-1), _loca_long(false), _loca(otf->table("loca")), _glyf(otf->table("glyf")), _hmtx(otf->table("hmtx")), _got_glyph_names(false), _got_unicodes(false) { OpenType::Data maxp(otf->table("maxp")); if (maxp.length() >= 6) _nglyphs = maxp.u16(4); OpenType::Head head(otf->table("head"), 0); if (head.ok()) _loca_long = head.index_to_loc_format() != 0; if (_loca_long) _loca.align_long(); int loca_onesize = (_loca_long ? 4 : 2); if (_nglyphs >= _loca.length() / loca_onesize) _nglyphs = (_loca.length() / loca_onesize) - 1; // horizontal metrics OpenType::Data hhea(_otf->table("hhea")); // HHEA format: // 0 Fixed Table version number 0x00010000 for version 1.0. // 4 FWORD Ascender // 6 FWORD Descender // 8 FWORD LineGap // 10 UFWORD advanceWidthMax // 12 FWORD minLeftSideBearing // 14 FWORD minRightSideBearing // 16 FWORD xMaxExtent // 18 SHORT caretSlopeRise // 20 SHORT caretSlopeRun // 22 SHORT caretOffset // 24 SHORT (reserved) // 26 SHORT (reserved) // 28 SHORT (reserved) // 30 SHORT (reserved) // 32 SHORT metricDataFormat // 34 USHORT numberOfHMetrics if (hhea.length() >= 36 && hhea.u32(0) == 0x10000) _nhmtx = hhea.u16(34); if (_nhmtx * 4 > _hmtx.length()) _nhmtx = _hmtx.length() / 4; } TrueTypeBoundsCharstringProgram::~TrueTypeBoundsCharstringProgram() { for (Charstring **cs = _charstrings.begin(); cs < _charstrings.end(); cs++) delete *cs; } void TrueTypeBoundsCharstringProgram::font_matrix(double matrix[6]) const { matrix[0] = matrix[3] = 1.0 / _otf->units_per_em(); matrix[1] = matrix[2] = matrix[4] = matrix[5] = 0; } int TrueTypeBoundsCharstringProgram::nglyphs() const { return _nglyphs; } PermString TrueTypeBoundsCharstringProgram::glyph_name(int gi) const { // generate glyph names based on what pdftex can understand if (gi == 0) return PermString(".notdef"); // try 'post' table glyph names if (!_got_glyph_names) { OpenType::Post post(_otf->table("post")); if (post.ok()) post.glyph_names(_glyph_names); HashMap name2glyph(-1); // some 'post' tables are bogus, reject multiply-encoded names for (int gi = 0; gi < _glyph_names.size(); ++gi) { int& xgi = name2glyph.find_force(_glyph_names[gi]); if (xgi == -1) xgi = gi; else if (xgi == 0) _glyph_names[gi] = PermString(); else _glyph_names[gi] = _glyph_names[xgi] = PermString(); } _got_glyph_names = true; } if (gi >= 0 && gi < _glyph_names.size() && _glyph_names[gi]) return _glyph_names[gi]; // try 'uniXXXX' names if (!_got_unicodes) { OpenType::Cmap cmap(_otf->table("cmap")); if (cmap.ok()) { Vector > ugp; cmap.unmap_all(ugp); std::sort(ugp.begin(), ugp.end()); for (Vector >::iterator it = ugp.begin(); it != ugp.end(); ) { Vector >::iterator nit = it + 1; // ignore code points with multiple glyph mappings if (nit == ugp.end() || nit->first != it->first) { if (it->second >= _unicodes.size()) _unicodes.resize(it->second + 1, 0); if (!_unicodes[it->second]) _unicodes[it->second] = it->first; } else while (nit != ugp.end() && nit->first == it->first) ++nit; it = nit; } } _got_unicodes = true; } if (gi >= 0 && gi < _unicodes.size() && _unicodes[gi] > 0 && _unicodes[gi] <= 0xFFFF) { char buf[10]; sprintf(buf, "uni%04X", _unicodes[gi]); return PermString(buf); } else return permprintf("index%d", gi); } void TrueTypeBoundsCharstringProgram::glyph_names(Vector &gn) const { gn.clear(); for (int gi = 0; gi < _nglyphs; gi++) gn.push_back(glyph_name(gi)); } Charstring * TrueTypeBoundsCharstringProgram::glyph(int gi) const { if (gi < 0 || gi >= _nglyphs) return 0; if (_charstrings.size() <= gi) _charstrings.resize(gi + 1, (Charstring *) 0); if (!_charstrings[gi]) { // calculate glyf offsets uint32_t offset, end_offset; if (_loca_long) { offset = _loca.u32(gi * 4); end_offset = _loca.u32(gi * 4 + 4); } else { offset = _loca.u16(gi * 2) * 2; end_offset = _loca.u16(gi * 2 + 2) * 2; } // fetch bounding box from glyf int ncontours, xmin, ymin, xmax, ymax; if (offset != end_offset) { if (offset > end_offset || offset + 10 > end_offset || end_offset > (uint32_t) _glyf.length()) return 0; ncontours = _glyf.s16(offset); xmin = _glyf.s16(offset + 2); ymin = _glyf.s16(offset + 4); xmax = _glyf.s16(offset + 6); ymax = _glyf.s16(offset + 8); } else ncontours = xmin = ymin = xmax = ymax = 0; // fetch horizontal metrics int advance_width, lsb; if (gi >= _nhmtx) { advance_width = (_nhmtx ? _hmtx.u16((_nhmtx - 1) * 4) : 0); int hmtx_offset = _nhmtx * 4 + (gi - _nhmtx) * 2; lsb = (hmtx_offset + 2 <= _hmtx.length() ? _hmtx.s16(hmtx_offset) : 0); } else { advance_width = _hmtx.u16(gi * 4); lsb = _hmtx.s16(gi * 4 + 2); } // make charstring Type1CharstringGen gen; if (ncontours == 0) { gen.gen_number(0, 'X'); gen.gen_number(advance_width); gen.gen_command(Charstring::cHsbw); } else { gen.gen_number(lsb, 'X'); gen.gen_number(advance_width); gen.gen_command(Charstring::cHsbw); gen.gen_moveto(Point(xmin, ymin), false, false); if (xmax != xmin || ymax == ymin) gen.gen_number(xmax - xmin, 'x'); if (ymax != ymin) gen.gen_number(ymax - ymin, 'y'); gen.gen_command(ymax == ymin ? Charstring::cHlineto : (xmax == xmin ? Charstring::cVlineto : Charstring::cRlineto)); gen.gen_command(Charstring::cClosepath); } gen.gen_command(Charstring::cEndchar); _charstrings[gi] = gen.output(); } return _charstrings[gi]; } } lcdf-typetools-2.108/libefont/afmparse.cc0000644000175000017500000002452313423375327015343 00000000000000// -*- related-file-name: "../include/efont/afmparse.hh" -*- /* afmparse.{cc,hh} -- Adobe Font Metrics parsing * * Copyright (c) 1998-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #if HAVE_BROKEN_STRTOD # define strtod good_strtod #endif namespace Efont { static bool name_enders[256]; static char xvalue[256]; AfmParser::AfmParser(Slurper &slurp) : _slurper(slurp), _line(0), _pos(0), _length(0) { static_initialize(); } void AfmParser::trim_end() { int l = _length - 1; while (l >= 0 && isspace(_line[l])) { _line[l] = 0; l--; } _length = l + 1; } void AfmParser::static_initialize() { if (name_enders[(uint8_t)'(']) return; name_enders[(uint8_t)' '] = name_enders[(uint8_t)'\t'] = name_enders[(uint8_t)'\r'] = name_enders[(uint8_t)'\f'] = name_enders[(uint8_t)'\v'] = name_enders[(uint8_t)'\n'] = name_enders[(uint8_t)'\0'] = name_enders[(uint8_t)'['] = name_enders[(uint8_t)']'] = name_enders[(uint8_t)'/'] = name_enders[(uint8_t)'('] = name_enders[(uint8_t)')'] = name_enders[(uint8_t)';'] = true; xvalue[(uint8_t)'0'] = 0; xvalue[(uint8_t)'1'] = 1; xvalue[(uint8_t)'2'] = 2; xvalue[(uint8_t)'3'] = 3; xvalue[(uint8_t)'4'] = 4; xvalue[(uint8_t)'5'] = 5; xvalue[(uint8_t)'6'] = 6; xvalue[(uint8_t)'7'] = 7; xvalue[(uint8_t)'8'] = 8; xvalue[(uint8_t)'9'] = 9; xvalue[(uint8_t)'a'] = 10; xvalue[(uint8_t)'b'] = 11; xvalue[(uint8_t)'c'] = 12; xvalue[(uint8_t)'d'] = 13; xvalue[(uint8_t)'e'] = 14; xvalue[(uint8_t)'f'] = 15; xvalue[(uint8_t)'A'] = 10; xvalue[(uint8_t)'B'] = 11; xvalue[(uint8_t)'C'] = 12; xvalue[(uint8_t)'D'] = 13; xvalue[(uint8_t)'E'] = 14; xvalue[(uint8_t)'F'] = 15; } // isall == is total == is all of the string // %s whitespace-terminated PermString - non-zero-length // %/s name-terminated PermString - non-zero-length // %+s rest of line PermString // %= rest of line/until next `=' PermString; beginning & ending spaces // elided // %d integer // %g number // %x hex integer // %b boolean // %c character // %< hex string; argument is String *stored // %. any non-alphanumeric // ???????????? EOS vs. don't-skip-to-EOS ??????????? #define FAIL(s) do { _message = s; return 0; } while (0) unsigned char * AfmParser::vis(const char *formatsigned, va_list valist) { const unsigned char *format = (const unsigned char *)formatsigned; unsigned char *str = _pos; // Oftentimes, we'll get a keyword first. So handle that simple case // with a tight loop for (possibly) better performance and slightly different // semantics. (A keyword that comes first in the format must be followed // by a nonalphanumeric in the input to match.) if (isalpha(*format)) { bool ok = true; for (; *format && *format != ' ' && ok; format++, str++) { assert(isalnum(*format)); if (*format != *str) ok = false; } if (!ok || isalnum(*str)) { if (_message) return 0; _fail_field = -1; FAIL("keyword mismatch"); } } int fplus, fslash; _fail_field = 0; _message = PermString(); while (1) { switch (*format) { /* - - - - - - - - percent specifications - - - - - - - */ case '%': fplus = fslash = 0; _fail_field++; percentspec: switch (*++format) { // FLAGS case '+': fplus++; goto percentspec; case '/': fslash++; goto percentspec; case '%': goto matchchar; case 'b': case 's': { int len; if (fplus) len = strlen((char *)str); else if (fslash) { for (len = 0; !name_enders[ str[len] ]; len++) ; if (len == 0) FAIL("should be a string"); } else { for (len = 0; !isspace(str[len]) && str[len]; len++) ; if (len == 0) FAIL("should be a string"); } PermString s = PermString((char *)str, len); str += len; // Now we have the string. What to do with it? Depends on format. if (*format == 'b') { bool *bstore = va_arg(valist, bool *); if (s == "true") { if (bstore) *bstore = 1; } else if (s == "false") { if (bstore) *bstore = 0; } else FAIL("should be `true' or `false'"); } else { PermString *sstore = va_arg(valist, PermString *); if (sstore) *sstore = s; } break; } case '(': { if (*str++ != '(') FAIL("should be a parenthesized string"); unsigned char *last = str; int paren_level = 0; while (*last && paren_level >= 0) { if (*last == '(') paren_level++; if (*last == ')') paren_level--; last++; } if (paren_level >= 0) FAIL("had unbalanced parentheses"); PermString *sstore = va_arg(valist, PermString *); if (sstore) *sstore = PermString((char *)str, last - str - 1); str = last; break; } case 'd': case 'i': { union { unsigned char *uc; char *c; } new_str; int v = strtol((char *)str, &new_str.c, 10); if (new_str.uc == str) FAIL("should be an integer"); str = new_str.uc; int *istore = va_arg(valist, int *); if (istore) *istore = v; break; } case 'x': { union { unsigned char *uc; char *c; } new_str; int v = strtol((char *)str, &new_str.c, 16); if (new_str.uc == str) FAIL("should be a hex integer"); str = new_str.uc; int *istore = va_arg(valist, int *); if (istore) *istore = v; break; } case 'e': case 'f': case 'g': { union { unsigned char *uc; char *c; } new_str; double v = strtonumber((char *)str, &new_str.c); if (v < MIN_KNOWN_DOUBLE) v = MIN_KNOWN_DOUBLE; if (new_str.uc == str) FAIL("should be a real number"); str = new_str.uc; double *dstore = va_arg(valist, double *); if (dstore) *dstore = v; break; } case '<': { unsigned char *endbrack = (unsigned char *)strchr((char *)str, '>'); int n = (endbrack ? endbrack - (str + 1) : 0); if (!endbrack || n % 2 != 0) FAIL("should be hex values in "); String s = String::make_uninitialized(n/2); unsigned char *data = s.mutable_udata(); str++; while (*str != '>') { if (isxdigit(str[0]) && isxdigit(str[1])) { *data++ = xvalue[str[0]] * 16 + xvalue[str[1]]; str += 2; } else FAIL("had non-hex digits in the angle brackets"); } str++; if (String *datastore = va_arg(valist, String *)) *datastore = s; break; } default: assert(0 /* internal error: bad % */); FAIL(""); } break; /* - - - - - - - - end percent specifications - - - - - - - */ case ' ': if (!isspace(*str)) FAIL("should be followed by whitespace"); /* FALLTHRU */ case '-': while (isspace(*str)) str++; break; case 0: // always eat space at end of format while (isspace(*str)) str++; return str; default: matchchar: if (*str++ != *format) FAIL(permprintf("- expected `%c'", *format)); break; } format++; } } bool AfmParser::isall(const char *format, ...) { va_list valist; va_start(valist, format); unsigned char *new_pos = vis(format, valist); va_end(valist); if (new_pos && *new_pos == 0) { _pos = new_pos; return 1; } else return 0; } bool AfmParser::is(const char *format, ...) { va_list valist; va_start(valist, format); unsigned char *new_pos = vis(format, valist); va_end(valist); if (new_pos) { _pos = new_pos; return 1; } else return 0; } PermString AfmParser::keyword() const { const char *f = (const char *)_pos; while (isspace((unsigned char) *f)) f++; const char *l = f; while (isalnum((unsigned char) *l) || *l == '_') l++; return PermString(f, l - f); } void AfmParser::skip_until(unsigned char c) { while (*_pos && *_pos != c) _pos++; } } lcdf-typetools-2.108/libefont/t1cs.cc0000644000175000017500000002710113423375327014412 00000000000000// -*- related-file-name: "../include/efont/t1cs.hh" -*- /* t1cs.{cc,hh} -- Type 1/2 charstrings * * Copyright (c) 1998-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include namespace Efont { const char * const Charstring::command_names[] = { "error", "hstem", "UNKNOWN_2", "vstem", "vmoveto", "rlineto", "hlineto", "vlineto", "rrcurveto", "closepath", "callsubr", "return", "escape", "hsbw", "endchar", "UNKNOWN_15", "blend", "UNKNOWN_17", "hstemhm", "hintmask", "cntrmask", "rmoveto", "hmoveto", "vstemhm", "rcurveline", "rlinecurve", "vvcurveto", "hhcurveto", "shortint", "callgsubr", "vhcurveto", "hvcurveto", "dotsection", "vstem3", "hstem3", "and", "or", "not", "seac", "sbw", "store", "abs", "add", "sub", "div", "load", "neg", "eq", "callothersubr", "pop", "drop", "UNKNOWN_12_19", "put", "get", "ifelse", "random", "mul", "UNKNOWN_12_25", "sqrt", "dup", "exch", "index", "roll", "UNKNOWN_12_31", "UNKNOWN_12_32", "setcurrentpoint", "hflex", "flex", "hflex1", "flex1" }; const char * const Charstring::standard_encoding[256] = { /* 00x */ 0, 0, 0, 0, 0, 0, 0, 0, /* 01x */ 0, 0, 0, 0, 0, 0, 0, 0, /* 02x */ 0, 0, 0, 0, 0, 0, 0, 0, /* 03x */ 0, 0, 0, 0, 0, 0, 0, 0, /* 04x */ "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quoteright", /* 05x */ "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", /* 06x */ "zero", "one", "two", "three", "four", "five", "six", "seven", /* 07x */ "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", /* 10x */ "at", "A", "B", "C", "D", "E", "F", "G", /* 11x */ "H", "I", "J", "K", "L", "M", "N", "O", /* 12x */ "P", "Q", "R", "S", "T", "U", "V", "W", /* 13x */ "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", /* 14x */ "quoteleft", "a", "b", "c", "d", "e", "f", "g", /* 15x */ "h", "i", "j", "k", "l", "m", "n", "o", /* 16x */ "p", "q", "r", "s", "t", "u", "v", "w", /* 17x */ "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", 0, /* 20x */ 0, 0, 0, 0, 0, 0, 0, 0, /* 21x */ 0, 0, 0, 0, 0, 0, 0, 0, /* 22x */ 0, 0, 0, 0, 0, 0, 0, 0, /* 23x */ 0, 0, 0, 0, 0, 0, 0, 0, /* 24x */ 0, "exclamdown", "cent", "sterling", "fraction", "yen", "florin", "section", /* 25x */ "currency", "quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", "fl", /* 26x */ 0, "endash", "dagger", "daggerdbl", "periodcentered", 0, "paragraph", "bullet", /* 27x */ "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright", "ellipsis", "perthousand", 0, "questiondown", /* 30x */ 0, "grave", "acute", "circumflex", "tilde", "macron", "breve", "dotaccent", /* 31x */ "dieresis", 0, "ring", "cedilla", 0, "hungarumlaut", "ogonek", "caron", /* 32x */ "emdash", 0, 0, 0, 0, 0, 0, 0, /* 33x */ 0, 0, 0, 0, 0, 0, 0, 0, /* 34x */ 0, "AE", 0, "ordfeminine", 0, 0, 0, 0, /* 35x */ "Lslash", "Oslash", "OE", "ordmasculine", 0, 0, 0, 0, /* 36x */ 0, "ae", 0, 0, 0, "dotlessi", 0, 0, /* 37x */ "lslash", "oslash", "oe", "germandbls", 0, 0, 0, 0, }; Charstring::~Charstring() { } String Charstring::command_name(int cmd) { if (cmd >= 0 && cmd <= cLastCommand) return command_names[cmd]; else if (cmd < cEscapeDelta + 256) return String("COMMAND_12_") + String(cmd - cEscapeDelta); else return String(""); } Type1Charstring::Type1Charstring(int lenIV, const String &s) : Charstring(), _key(-1) { if (lenIV < 0) // no charstring encryption _s = s; else if (lenIV < s.length()) { const unsigned char *d = reinterpret_cast(s.data()); _key = t1R_cs; for (int i = 0; i < lenIV; i++, d++) _key = ((*d + _key) * (uint32_t) t1C1 + t1C2) & 0xFFFF; _s = s.substring(lenIV); } } void Type1Charstring::prepend(const Type1Charstring &t1cs) { if (_key >= 0) decrypt(); if (t1cs._key >= 0) t1cs.decrypt(); _s = t1cs._s + _s; } void Type1Charstring::decrypt() const { if (_key >= 0) { int r = _key; uint8_t *d = reinterpret_cast(_s.mutable_data()); for (int i = 0; i < _s.length(); i++, d++) { uint8_t encrypted = *d; *d = encrypted ^ (r >> 8); r = ((encrypted + r) * (uint32_t) t1C1 + t1C2) & 0xFFFF; } _key = -1; } } bool Type1Charstring::process(CharstringInterp &interp) const { const uint8_t *data = Type1Charstring::data(); int left = _s.length(); while (left > 0) { bool more; int ahead; if (*data >= 32 && *data <= 246) { // push small number more = interp.number(data[0] - 139); ahead = 1; } else if (*data < 32) { // a command if (*data == cEscape) { if (left < 2) goto runoff_error; more = interp.type1_command(cEscapeDelta + data[1]); ahead = 2; } else if (*data == cShortint) { // short integer if (left < 3) goto runoff_error; int16_t val = (data[1] << 8) | data[2]; more = interp.number(val); ahead = 3; } else { more = interp.type1_command(data[0]); ahead = 1; } } else if (*data >= 247 && *data <= 250) { // push medium number if (left < 2) goto runoff_error; int val = + ((data[0] - 247) << 8) + 108 + data[1]; more = interp.number(val); ahead = 2; } else if (*data >= 251 && *data <= 254) { // push negative medium number if (left < 2) goto runoff_error; int val = - ((data[0] - 251) << 8) - 108 - data[1]; more = interp.number(val); ahead = 2; } else { // 255: push huge number if (left < 5) goto runoff_error; int32_t val = ((uint32_t) data[1] << 24) | (data[2] << 16) | (data[3] << 8) | data[4]; more = interp.number(val); ahead = 5; } if (!more) return interp.error() == CharstringInterp::errOK; data += ahead; left -= ahead; } runoff_error: interp.error(CharstringInterp::errRunoff); return false; } int Type1Charstring::first_caret_after(int pos) const { const uint8_t *data = Type1Charstring::data(); const uint8_t *edata = data + (pos < length() ? pos : length()); while (data < edata) { if (*data >= 32 && *data <= 246) // push small number data++; else if (*data < 32) { // a command if (*data == cEscape) data += 2; else if (*data == cShortint) data += 3; else data++; } else if (*data >= 247 && *data <= 254) // push medium number data += 2; else // 255: push huge number data += 5; } const uint8_t *odata = Type1Charstring::data(); return (data > odata + length() ? length() : data - odata); } void Type1Charstring::assign_substring(int pos, int len, const String &cs) { if (_key >= 0) decrypt(); if (pos < 0 || len < 0 || pos + len >= _s.length()) /* do nothing */; else if (cs.length() == len) { char *d = _s.mutable_data(); memcpy(d + pos, cs.data(), cs.length()); } else if (cs.length() <= len) { char *d = _s.mutable_data(); memcpy(d + pos, cs.data(), cs.length()); memmove(d + pos + cs.length(), d + pos + len, _s.length() - pos - len); _s = _s.substring(0, cs.length() - len); } else _s = _s.substring(0, pos) + cs + _s.substring(pos + len); } bool Type2Charstring::process(CharstringInterp &interp) const { const uint8_t *data = Type2Charstring::data(); int left = _s.length(); while (left > 0) { bool more; int ahead; if (*data >= 32 && *data <= 246) { // push small number more = interp.number(data[0] - 139); ahead = 1; } else if (*data < 32) { // a command if (*data == cEscape) { if (left < 2) goto runoff_error; more = interp.type2_command(cEscapeDelta + data[1], 0, 0); ahead = 2; } else if (*data == cShortint) { // short integer if (left < 3) goto runoff_error; int16_t val = (data[1] << 8) | data[2]; more = interp.number(val); ahead = 3; } else if (*data == cHintmask || *data == cCntrmask) { int left_ptr = left - 1; more = interp.type2_command(data[0], data + 1, &left_ptr); ahead = 1 + (left - 1) - left_ptr; } else { more = interp.type2_command(data[0], 0, 0); ahead = 1; } } else if (*data >= 247 && *data <= 250) { // push medium number if (left < 2) goto runoff_error; int val = + ((data[0] - 247) << 8) + 108 + data[1]; more = interp.number(val); ahead = 2; } else if (*data >= 251 && *data <= 254) { // push negative medium number if (left < 2) goto runoff_error; int val = - ((data[0] - 251) << 8) - 108 - data[1]; more = interp.number(val); ahead = 2; } else { // 255: push huge number if (left < 5) goto runoff_error; int32_t val = (data[1] << 24) | (data[2] << 16) | (data[3] << 8) | data[4]; more = interp.number(val / 65536.); ahead = 5; } if (!more) return interp.error() == CharstringInterp::errOK; data += ahead; left -= ahead; } runoff_error: interp.error(CharstringInterp::errRunoff); return false; } CharstringProgram::CharstringProgram(unsigned units_per_em) : _parent_program(false), _units_per_em(units_per_em ? units_per_em : 1000) { } const CharstringProgram * CharstringProgram::child_program(int) const { return this; } void CharstringProgram::font_matrix(double matrix[6]) const { matrix[0] = matrix[3] = 0.001; matrix[1] = matrix[2] = matrix[4] = matrix[5] = 0; } void CharstringProgram::glyph_names(Vector &gnames) const { int n = nglyphs(); gnames.resize(n); for (int i = 0; i < n; i++) gnames[i] = glyph_name(i); } Vector * CharstringProgram::mm_vector(VectorType, bool) const { return 0; } double CharstringProgram::global_width_x(bool) const { return UNKDOUBLE; } } lcdf-typetools-2.108/libefont/otfcmap.cc0000644000175000017500000004163313423375327015177 00000000000000// -*- related-file-name: "../include/efont/otfcmap.hh" -*- /* otfcmap.{cc,hh} -- OpenType cmap table * * Copyright (c) 2002-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include // for ntohl() #define USHORT_AT(d) (Data::u16_aligned(d)) #define SHORT_AT(d) (Data::s16_aligned(d)) #define ULONG_AT(d) (Data::u32_aligned(d)) #define ULONG_AT2(d) (Data::u32_aligned16(d)) namespace Efont { namespace OpenType { Cmap::Cmap(const String &s, ErrorHandler *errh) : _str(s) { _str.align(4); _error = parse_header(errh ? errh : ErrorHandler::silent_handler()); } int Cmap::parse_header(ErrorHandler *errh) { // HEADER FORMAT: // USHORT version // USHORT numTables int len = _str.length(); const uint8_t *data = _str.udata(); if (HEADER_SIZE > len) return errh->error("OTF cmap too small"), -EFAULT; if (!(data[0] == '\000' && data[1] == '\000')) return errh->error("bad cmap version number"), -ERANGE; _ntables = USHORT_AT(data + 2); if (_ntables == 0) return errh->error("OTF cmap contains no tables"), -EINVAL; if (HEADER_SIZE + ENCODING_SIZE * _ntables > len) return errh->error("cmap directory out of range"), -EFAULT; // ENCODING ENTRY FORMAT: // USHORT platformID // USHORT encodingID // ULONG offset int last_platform = -1; int last_encoding = -1; int last_language = -1; _first_unicode_table = -1; for (int i = 0; i < _ntables; i++) { int loc = HEADER_SIZE + ENCODING_SIZE * i; int platform = USHORT_AT(data + loc); int encoding = USHORT_AT(data + loc + 2); uint32_t offset = ULONG_AT(data + loc + 4); if (offset + 8 > (uint32_t) len) { length_error: return errh->error("encoding data for entry %d out of range", i); } int format = USHORT_AT(data + offset); int language; if (format == F_BYTE || format == F_HIBYTE || format == F_SEGMENTED || format == F_TRIMMED) { if (USHORT_AT(data + offset + 2) < 6) goto length_error; language = USHORT_AT(data + offset + 4); } else if (format == F_HIBYTE32 || format == F_TRIMMED32 || format == F_SEGMENTED32) { if (offset + 12 > (uint32_t) len || ULONG_AT2(data + offset + 4) < 12) goto length_error; language = ULONG_AT2(data + offset + 8); } else continue; if (!(platform > last_platform || (platform == last_platform && (encoding > last_encoding || (encoding == last_encoding && language > last_language))))) errh->warning("unsorted cmap encoding records at entry %d (%d,%d,%d follows %d,%d,%d)", i, platform, encoding, language, last_platform, last_encoding, last_language); if ((platform == 0 || (platform == 3 && encoding == 1)) && _first_unicode_table < 0) _first_unicode_table = i; last_platform = platform, last_encoding = encoding, last_language = language; } _table_error.assign(_ntables, -2); return 0; } int Cmap::first_table(int platform, int encoding) const { if (error() < 0) return -1; const uint8_t *data = _str.udata(); data += HEADER_SIZE; for (int i = 0; i < _ntables; i++, data += ENCODING_SIZE) { int p = USHORT_AT(data), e = USHORT_AT(data + 2); if (platform == p && (encoding < 0 || encoding == e)) return i; } return -1; } int Cmap::check_table(int t, ErrorHandler *errh) const { if (!errh) errh = ErrorHandler::silent_handler(); if (t == USE_FIRST_UNICODE_TABLE && _first_unicode_table == -1) { errh->warning("font appears not to support Unicode"); _first_unicode_table = 0; } if (t == USE_FIRST_UNICODE_TABLE) t = _first_unicode_table; if (_error < 0 || t < 0 || t >= _ntables) return errh->error("no such table"); if (_table_error[t] != -2) return _table_error[t]; _table_error[t] = -1; const uint8_t *data = table_data(t); uint32_t left = _str.uend() - data; int format = USHORT_AT(data); uint32_t length = 0; // value not used switch (format) { case F_BYTE: if (left < 4 || (length = USHORT_AT(data + 2)) > left || length != 259) return errh->error("bad table %d length (format %d)", t, format); break; case F_HIBYTE: if (left < 4 || (length = USHORT_AT(data + 2)) > left || length < 524) return errh->error("bad table %d length (format %d)", t, format); for (int hi_byte = 0; hi_byte < 256; hi_byte++) if (uint32_t subh_key = USHORT_AT(data + 6 + 2 * hi_byte)) { if ((subh_key & 7) || HIBYTE_SUBHEADERS + subh_key + 8 > length) return errh->error("bad table %d subheader %d offset (format 2)", t, hi_byte); const uint8_t *subh = data + HIBYTE_SUBHEADERS + subh_key; int firstCode = USHORT_AT(subh); int entryCount = USHORT_AT(subh + 2); int idRangeOffset = USHORT_AT(subh + 6); if (firstCode + entryCount > 256 || entryCount == 0) return errh->error("bad table %d subheader %d contents (format 2)", t, hi_byte); if ((HIBYTE_SUBHEADERS + subh_key + 6) // pos[idRangeOffset] + idRangeOffset + entryCount * 2 > length) return errh->error("bad table %d subheader %d length (format 2)", t, hi_byte); } break; case F_SEGMENTED: { if (left < 4 || (length = USHORT_AT(data + 2)) > left || length < 16) return errh->error("bad table %d length (format %d)", t, format); int segCountX2 = USHORT_AT(data + 6); int searchRange = USHORT_AT(data + 8); int entrySelector = USHORT_AT(data + 10); int rangeShift = USHORT_AT(data + 12); if ((segCountX2 & 1) || segCountX2 == 0 || (searchRange & (searchRange - 1)) /* not a power of 2? */ || searchRange <= segCountX2/2 || (searchRange>>1) > segCountX2/2 || 1 << (entrySelector + 1) != searchRange || rangeShift != segCountX2 - searchRange) return errh->error("bad table %d segment counts (format %d)", format); uint32_t segCount = segCountX2 >> 1; if (length < 16 + 8 * segCount) return errh->error("bad table %d length (format %d, length %u, need %u)", t, format, length, 16 + 8 * segCount); const uint8_t *endCodes = data + 14; const uint8_t *startCodes = endCodes + 2 + segCountX2; const uint8_t *idDeltas = startCodes + segCountX2; const uint8_t *idRangeOffsets = idDeltas + segCountX2; uint32_t idRangeOffsetsPos = idRangeOffsets - data; int last_end = 0; for (int i = 0; i < segCountX2; i += 2) { int endCode = USHORT_AT(endCodes + i); int startCode = USHORT_AT(startCodes + i); /* int idDelta = SHORT_AT(idDeltas + i); // not needed */ int idRangeOffset = USHORT_AT(idRangeOffsets + i); if (endCode < startCode || startCode < last_end) return errh->error("bad table %d overlapping range %d (format %d)", t, i/2, format); if (idRangeOffset && idRangeOffset != 65535 && idRangeOffsetsPos + i + idRangeOffset + (endCode - startCode)*2 + 2 > length) return errh->error("bad table %d range %d length (format %d, range %d-%d, idRangeOffset %d, length %u)", t, i/2, format, startCode, endCode, idRangeOffset, length); last_end = endCode + 1; } if (USHORT_AT(endCodes + segCountX2 - 2) != 0xFFFF) return errh->error("bad table %d incorrect final endCode (format 4)", t); break; } case F_TRIMMED: { if (left < 4 || (length = USHORT_AT(data + 2)) > left || length < 10) return errh->error("bad table %d length (format %d)", t, format); uint32_t entryCount = USHORT_AT(data + 8); if (10 + entryCount * 2 > length) return errh->error("bad table %d length (format %d)", t, format); break; } case F_SEGMENTED32: { if (left < 8 || (length = ULONG_AT(data + 4)) > left || length < 16) return errh->error("bad table %d length (format %d)", t, format); uint32_t nGroups = ULONG_AT(data + 16); if ((length - 16) / 12 < nGroups) return errh->error("bad table %d length (format %d)", t, format); uint32_t last_post_end = 0; data += 16; for (uint32_t i = 0; i < nGroups; i++, data += 12) { uint32_t startCharCode = ULONG_AT(data); uint32_t endCharCode = ULONG_AT(data + 4); if (startCharCode < last_post_end || endCharCode < startCharCode) return errh->error("bad table %d overlapping range %d (format %d)", t, i, format); last_post_end = endCharCode + 1; } break; } case F_HIBYTE32: case F_TRIMMED32: default: return errh->error("bad table %d unsupported format %d", t, format); } _table_error[t] = t; return t; } Glyph Cmap::map_table(int t, uint32_t uni, ErrorHandler *errh) const { if ((t = check_table(t, errh)) < 0) return 0; const uint8_t *data = table_data(t); switch (USHORT_AT(data)) { case F_BYTE: if (uni < 256) return data[6 + uni]; else return 0; case F_HIBYTE: { if (uni >= 65536) return 0; int hi_byte = (uni >> 8) & 255; int subh = USHORT_AT(data + 6 + hi_byte * 2); if (subh == 0 && hi_byte) // XXX? return 0; data += 524 + subh; int firstCode = USHORT_AT(data); int entryCount = USHORT_AT(data + 2); int idDelta = SHORT_AT(data + 4); int idRangeOffset = USHORT_AT(data + 6); int lo_byte = uni & 255; if (lo_byte < firstCode || lo_byte >= firstCode + entryCount) return 0; int answer = USHORT_AT(data + 6 + idRangeOffset + (lo_byte - firstCode) * 2); if (answer == 0) return 0; return (answer + idDelta) & 65535; } case F_SEGMENTED: { if (uni >= 65536) return 0; int segCount = USHORT_AT(data + 6) >> 1; const uint8_t *endCounts = data + 14; const uint8_t *startCounts = endCounts + (segCount << 1) + 2; const uint8_t *idDeltas = startCounts + (segCount << 1); const uint8_t *idRangeOffsets = idDeltas + (segCount << 1); int l = 0, r = segCount; while (l < r) { int m = l + (r - l) / 2; uint32_t endCount = USHORT_AT(endCounts + (m << 1)); uint32_t startCount = USHORT_AT(startCounts + (m << 1)); if (uni < startCount) r = m; else if (uni <= endCount) { int idDelta = SHORT_AT(idDeltas + (m << 1)); int idRangeOffset = USHORT_AT(idRangeOffsets + (m << 1)); if (idRangeOffset == 0) return (idDelta + uni) & 65535; else if (idRangeOffset == 65535) return 0; int g = USHORT_AT(idRangeOffsets + (m << 1) + idRangeOffset + ((uni - startCount) << 1)); if (g == 0) return 0; return (idDelta + g) & 65535; } else l = m + 1; } return 0; } case F_TRIMMED: { uint32_t firstCode = USHORT_AT(data + 6); uint32_t entryCount = USHORT_AT(data + 8); if (uni < firstCode || uni >= firstCode + entryCount) return 0; return USHORT_AT(data + 10 + ((uni - firstCode) << 1)); } case F_SEGMENTED32: { uint32_t nGroups = ULONG_AT2(data + 12); uint32_t l = 0, r = nGroups; const uint8_t *groups = data + 16; while (l < r) { uint32_t m = l + (r - l) / 2; uint32_t startCharCode = ULONG_AT2(groups + m * 12); uint32_t endCharCode = ULONG_AT2(groups + m * 12 + 4); if (uni < startCharCode) r = m; else if (uni <= endCharCode) return ULONG_AT2(groups + m * 12 + 8) + uni - startCharCode; else l = m + 1; } return 0; } default: return 0; } } void Cmap::dump_table(int t, Vector > &ugp, ErrorHandler *errh) const { if ((t = check_table(t, errh)) < 0) return; const uint8_t *data = table_data(t); switch (USHORT_AT(data)) { case F_BYTE: for (uint32_t u = 0; u < 256; ++u) if (int g = data[6 + u]) ugp.push_back(std::make_pair(u, g)); break; case F_HIBYTE: assert(USHORT_AT(data + 6) == 0); for (int hi_byte = 0; hi_byte < 256; hi_byte++) { int subh = USHORT_AT(data + 6 + hi_byte * 4); if (subh == 0 && hi_byte > 0) continue; const uint8_t *tdata = data + 524 + subh; int firstCode = USHORT_AT(tdata); int entryCount = USHORT_AT(tdata + 2); int idDelta = SHORT_AT(tdata + 4); int idRangeOffset = USHORT_AT(tdata + 6); const uint8_t *gdata = tdata + 6 + idRangeOffset; for (int i = 0; i < entryCount; i++) if (Glyph g = USHORT_AT(gdata + (i << 1))) { g = (idDelta + g) & 65535; uint32_t u = (hi_byte << 8) + firstCode + i; ugp.push_back(std::make_pair(u, g)); } } break; case F_SEGMENTED: { int segCountX2 = USHORT_AT(data + 6); const uint8_t *endCounts = data + 14; const uint8_t *startCounts = endCounts + segCountX2 + 2; const uint8_t *idDeltas = startCounts + segCountX2; const uint8_t *idRangeOffsets = idDeltas + segCountX2; for (int i = 0; i < segCountX2; i += 2) { uint32_t endCount = USHORT_AT(endCounts + i); uint32_t startCount = USHORT_AT(startCounts + i); int idDelta = SHORT_AT(idDeltas + i); int idRangeOffset = USHORT_AT(idRangeOffsets + i); if (idRangeOffset == 0) { for (uint32_t u = startCount; u <= endCount; ++u) { Glyph g = (u + idDelta) & 65535; ugp.push_back(std::make_pair(u, g)); } } else { const uint8_t *gdata = idRangeOffsets + i + idRangeOffset; for (uint32_t u = startCount; u <= endCount; ++u, gdata += 2) if (Glyph g = USHORT_AT(gdata)) { g = (g + idDelta) & 65535; ugp.push_back(std::make_pair(u, g)); } } } break; } case F_TRIMMED: { uint32_t firstCode = USHORT_AT(data + 6); int entryCount = USHORT_AT(data + 8); for (int i = 0; i < entryCount; i++) if (Glyph g = USHORT_AT(data + 10 + (i << 1))) ugp.push_back(std::make_pair(firstCode + i, g)); break; } case F_SEGMENTED32: { uint32_t nGroups = ULONG_AT2(data + 12); const uint8_t *groups = data + 16; for (uint32_t i = 0; i < nGroups; i++, groups += 12) { uint32_t startCharCode = ULONG_AT2(groups); uint32_t nCharCodes = ULONG_AT2(groups + 4) - startCharCode; Glyph startGlyphID = ULONG_AT2(groups + 8); for (uint32_t i = 0; i <= nCharCodes; i++) ugp.push_back(std::make_pair(startCharCode + i, startGlyphID + i)); } break; } default: break; } } int Cmap::map_uni(const Vector &vin, Vector &vout) const { int t; if ((t = check_table(USE_FIRST_UNICODE_TABLE)) < 0) return -1; vout.resize(vin.size(), 0); for (int i = 0; i < vin.size(); i++) vout[i] = map_table(t, vin[i]); return 0; } }} lcdf-typetools-2.108/libefont/Makefile.am0000664000175000017500000000123412732752520015262 00000000000000## Process this file with automake to produce Makefile.in AUTOMAKE_OPTIONS = foreign noinst_LIBRARIES = libefont.a libefont_a_SOURCES = \ afm.cc \ afmparse.cc \ afmw.cc \ amfm.cc \ cff.cc \ encoding.cc \ findmet.cc \ metrics.cc \ otf.cc \ otfcmap.cc \ otfdata.cc \ otfdescrip.cc \ otfgpos.cc \ otfgsub.cc \ otfname.cc \ otfos2.cc \ otfpost.cc \ pairop.cc \ psres.cc \ t1bounds.cc \ t1cs.cc \ t1csgen.cc \ t1interp.cc \ t1item.cc \ t1font.cc \ t1fontskel.cc \ t1mm.cc \ t1rw.cc \ t1unparser.cc \ ttfcs.cc \ ttfhead.cc \ ttfkern.cc libefont_a_LIBADD = @TEMPLATE_OBJS@ CLEANFILES = @TEMPLATE_OBJS@ AM_CPPFLAGS = -I$(srcdir)/../include lcdf-typetools-2.108/libefont/t1mm.cc0000644000175000017500000002477613423375327014435 00000000000000// -*- related-file-name: "../include/efont/t1mm.hh" -*- /* t1mm.{cc,hh} -- Type 1 multiple master font information * * Copyright (c) 1998-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include namespace Efont { MultipleMasterSpace::MultipleMasterSpace(PermString fn, int na, int nm) : CharstringProgram(1000), _ok(false), _font_name(fn), _naxes(na), _nmasters(nm), _axis_types(na, PermString()), _axis_labels(na, PermString()), _design_vector(0), _norm_design_vector(0), _weight_vector(0) { } void MultipleMasterSpace::set_master_positions(const Vector &mp) { _master_positions = mp; } void MultipleMasterSpace::set_normalize(const Vector &nin, const Vector &nout) { _normalize_in = nin; _normalize_out = nout; } void MultipleMasterSpace::set_axis_type(int ax, PermString t) { _axis_types[ax] = t; } void MultipleMasterSpace::set_axis_label(int ax, PermString t) { _axis_labels[ax] = t; } void MultipleMasterSpace::set_design_vector(const NumVector &v) { _default_design_vector = v; } void MultipleMasterSpace::set_weight_vector(const NumVector &v) { _default_weight_vector = v; } PermString MultipleMasterSpace::axis_abbreviation(PermString atype) { if (atype == "Weight") return "wt"; else if (atype == "Width") return "wd"; else if (atype == "OpticalSize") return "op"; else if (atype == "Style") return "st"; else return atype; } bool MultipleMasterSpace::error(ErrorHandler *errh, const char *s, ...) const { if (errh) { char buf[1024]; va_list val; va_start(val, s); assert(strlen(s) < 800); sprintf(buf, (s[0] == ' ' ? "%.200s%s" : "%.200s: %s"), _font_name.c_str(), s); errh->xmessage(ErrorHandler::e_error, buf, val); va_end(val); } return false; } bool MultipleMasterSpace::check(ErrorHandler *errh) { if (_ok) return true; if (_nmasters <= 0 || _nmasters > 16) return error(errh, "number of masters must be between 1 and 16"); if (_naxes <= 0 || _naxes > 4) return error(errh, "number of axes must be between 1 and 4"); if (_master_positions.size() != _nmasters) return error(errh, "bad BlendDesignPositions"); for (int i = 0; i < _nmasters; i++) if (_master_positions[i].size() != _naxes) return error(errh, "inconsistent BlendDesignPositions"); if (_normalize_in.size() != _naxes || _normalize_out.size() != _naxes) return error(errh, "bad BlendDesignMap"); for (int i = 0; i < _naxes; i++) if (_normalize_in[i].size() != _normalize_out[i].size()) return error(errh, "bad BlendDesignMap"); if (!_axis_types.size()) _axis_types.assign(_naxes, PermString()); if (_axis_types.size() != _naxes) return error(errh, "bad BlendAxisTypes"); if (!_axis_labels.size()) _axis_labels.assign(_naxes, PermString()); if (_axis_labels.size() != _naxes) return error(errh, "bad axis labels"); if (!_default_design_vector.size()) _default_design_vector.assign(_naxes, UNKDOUBLE); if (_default_design_vector.size() != _naxes) return error(errh, "inconsistent design vector"); if (!_default_weight_vector.size()) _default_weight_vector.assign(_nmasters, UNKDOUBLE); if (_default_weight_vector.size() != _nmasters) return error(errh, "inconsistent weight vector"); _ok = true; return true; } bool MultipleMasterSpace::check_intermediate(ErrorHandler *errh) { if (!_ok || _cdv) return true; for (int a = 0; a < _naxes; a++) for (int m = 0; m < _nmasters; m++) if (_master_positions[m][a] != 0 && _master_positions[m][a] != 1) { if (errh) errh->warning("%s requires intermediate master conversion programs", _font_name.c_str()); return false; } return true; } int MultipleMasterSpace::axis(PermString ax) const { for (int a = 0; a < _naxes; a++) if (_axis_types[a] == ax || _axis_labels[a] == ax) return a; return -1; } double MultipleMasterSpace::axis_low(int ax) const { return _normalize_in[ax][0]; } double MultipleMasterSpace::axis_high(int ax) const { return _normalize_in[ax].back(); } Vector MultipleMasterSpace::empty_design_vector() const { return Vector(_naxes, UNKDOUBLE); } bool MultipleMasterSpace::set_design(NumVector &design_vector, int ax, double value, ErrorHandler *errh) const { if (ax < 0 || ax >= _naxes) return error(errh, " has only %d axes", _naxes); if (value < axis_low(ax)) { value = axis_low(ax); if (errh) errh->warning("raising %s's %s to %g", _font_name.c_str(), _axis_types[ax].c_str(), value); } if (value > axis_high(ax)) { value = axis_high(ax); if (errh) errh->warning("lowering %s's %s to %g", _font_name.c_str(), _axis_types[ax].c_str(), value); } design_vector[ax] = value; return true; } bool MultipleMasterSpace::set_design(NumVector &design_vector, PermString ax_name, double val, ErrorHandler *errh) const { int ax = axis(ax_name); if (ax < 0) return error(errh, " has no `%s' axis", ax_name.c_str()); else return set_design(design_vector, ax, val, errh); } bool MultipleMasterSpace::normalize_vector(ErrorHandler *errh) const { NumVector &design = *_design_vector; NumVector &norm_design = *_norm_design_vector; for (int a = 0; a < _naxes; a++) if (!KNOWN(design[a])) { if (errh) errh->error("must specify %s's %s coordinate", _font_name.c_str(), _axis_types[a].c_str()); return false; } // Move to normalized design coordinates. norm_design.assign(_naxes, UNKDOUBLE); if (_ndv) { CharstringInterp ai; if (!ai.interpret(this, &_ndv)) return error(errh, "%s in NDV program", ai.error_string().c_str()); } else for (int a = 0; a < _naxes; a++) { double d = design[a]; double nd = UNKDOUBLE; const Vector &norm_in = _normalize_in[a]; const Vector &norm_out = _normalize_out[a]; if (d < norm_in[0]) nd = norm_out[0]; for (int i = 1; i < norm_in.size(); i++) if (d >= norm_in[i-1] && d < norm_in[i]) { nd = norm_out[i-1] + ((d - norm_in[i-1]) * (norm_out[i] - norm_out[i-1]) / (norm_in[i] - norm_in[i-1])); goto done; } if (d >= norm_in.back()) nd = norm_out.back(); done: norm_design[a] = nd; } for (int a = 0; a < _naxes; a++) if (!KNOWN(norm_design[a])) return error(errh, "bad normalization"); return true; } bool MultipleMasterSpace::convert_vector(ErrorHandler *errh) const { NumVector &norm_design = *_norm_design_vector; NumVector &weight = *_weight_vector; weight.assign(_nmasters, 1); if (_cdv) { CharstringInterp ai; if (!ai.interpret(this, &_cdv)) return error(errh, "%s in CDV program", ai.error_string().c_str()); } else for (int a = 0; a < _naxes; a++) for (int m = 0; m < _nmasters; m++) { if (_master_positions[m][a] == 0) weight[m] *= 1 - norm_design[a]; else if (_master_positions[m][a] == 1) weight[m] *= norm_design[a]; else return error(errh, " requires intermediate master conversion programs"); } return true; } bool MultipleMasterSpace::design_to_norm_design(const NumVector &design_in, NumVector &norm_design, ErrorHandler *errh) const { NumVector design(design_in); NumVector weight; _design_vector = &design; _norm_design_vector = &norm_design; _weight_vector = &weight; if (!normalize_vector(errh)) return false; _design_vector = _norm_design_vector = _weight_vector = 0; return true; } bool MultipleMasterSpace::design_to_weight(const NumVector &design_in, NumVector &weight, ErrorHandler *errh) const { NumVector design(design_in); NumVector norm_design; bool dirty = false; for (int i = 0; i < _naxes; i++) if (design[i] != _default_design_vector[i]) dirty = true; if (dirty) { _design_vector = &design; _norm_design_vector = &norm_design; _weight_vector = &weight; if (!normalize_vector(errh)) return false; if (!convert_vector(errh)) return false; _design_vector = _norm_design_vector = _weight_vector = 0; } else weight = _default_weight_vector; double sum = 0; for (int m = 0; m < _nmasters; m++) sum += weight[m]; if (sum < 0.9999 || sum > 1.0001) return error(errh, "bad conversion: weight vector doesn't sum to 1"); // adjust weight vector to max 4 decimal digits of precision, and make it // sum to exactly 1 sum = 0; for (int m = 0; m < _nmasters - 1; m++) { weight[m] = floor(weight[m] * 10000. + 0.5) / 10000.; sum += weight[m]; } weight[_nmasters - 1] = 1 - sum; return true; } Vector * MultipleMasterSpace::mm_vector(VectorType t, bool writable) const { if (t == VEC_WEIGHT) return _weight_vector; else if (t == VEC_NORM_DESIGN) return _norm_design_vector; else if (t == VEC_DESIGN && !writable) return _design_vector; else return 0; } } lcdf-typetools-2.108/libefont/otfname.cc0000644000175000017500000001760513423375327015201 00000000000000// -*- related-file-name: "../include/efont/otfname.hh" -*- /* otfname.{cc,hh} -- OpenType name table * * Copyright (c) 2003-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #define USHORT_AT(d) (Data::u16_aligned(d)) namespace Efont { namespace OpenType { static const uint16_t mac_roman_encoding[] = { // 0x80-0x8F 0x00C4, 0x00C5, 0x00C7, 0x00C9, // Adieresis Aring Ccedilla Eacute 0x00D1, 0x00D6, 0x00DC, 0x00E1, // Ntilde Odieresis Udieresis aacute 0x00E0, 0x00E2, 0x00E4, 0x00E3, // agrave acircumflex adieresis atilde 0x00E5, 0x00E7, 0x00E9, 0x00E8, // aring ccedilla eacute egrave // 0x90-0x9F 0x00EA, 0x00EB, 0x00ED, 0x00EC, // ecircumflex edieresis iacute igrave 0x00EE, 0x00EF, 0x00F1, 0x00F3, // icircumflex idieresis ntilde oacute 0x00F2, 0x00F4, 0x00F6, 0x00F5, // ograve ocircumflex odieresis otilde 0x00FA, 0x00F9, 0x00FB, 0x00FC, // uacute ugrave ucircumflex udieresis // 0xA0-0xAF 0x2020, 0x00B0, 0x00A2, 0x00A3, // dagger degree cent sterling 0x00A7, 0x2022, 0x00B6, 0x00DF, // section bullet paragraph germandbls 0x00AE, 0x00A9, 0x2122, 0x00B4, // registered copyright trademark acute 0x00A8, 0x2260, 0x00C6, 0x00D8, // dieresis notequal AE Oslash // 0xB0-0xBF 0x221E, 0x00B1, 0x2264, 0x2265, // infinity plusminus lessequal greaterequal 0x00A5, 0x00B5, 0x2202, 0x2211, // yen mu partialdiff summation 0x220F, 0x03C0, 0x222B, 0x00AA, // product pi integral ordfeminine 0x00BA, 0x03A9, 0x00E6, 0x00F8, // ordmasculine Omegagreek ae oslash // 0xC0-0xCF 0x00BF, 0x00A1, 0x00AC, 0x221A, // questiondown exclamdown logicalnot radical 0x0192, 0x2248, 0x2206, 0x00AB, // florin approxequal increment guillemotleft 0x00BB, 0x2026, 0x00A0, 0x00C0, // guillemotright ellipsis nbspace Agrave 0x00C3, 0x00D5, 0x0152, 0x0153, // Atilde Otilde OE oe // 0xD0-0xDF 0x2013, 0x2014, 0x201C, 0x201D, // endash emdash quotedblleft quotedblright 0x2018, 0x2019, 0x00F7, 0x25CA, // quoteleft quoteright divide lozenge 0x00FF, 0x0178, 0x2044, 0x20AC, // ydieresis Ydieresis fraction Euro 0x2039, 0x203A, 0xFB01, 0xFB02, // guilsinglleft guilsinglright fi fl // 0xE0-0xEF 0x2021, 0x00B7, 0x201A, 0x201E, // daggerdbl middot quotesinglbase quotedblbase 0x2030, 0x00C2, 0x00CA, 0x00C1, // perthousand Acircumflex Ecircumflex Aacute 0x00CB, 0x00C8, 0x00CD, 0x00CE, // Edieresis Egrave Iacute Icircumflex 0x00CF, 0x00CC, 0x00D3, 0x00D4, // Idieresis Igrave Oacute Ocircumflex // 0xF0-0xFF 0xF8FF, 0x00D2, 0x00DA, 0x00DB, // apple Ograve Uacute Ucircumflex 0x00D9, 0x0131, 0x02C6, 0x02DC, // Ugrave dotlessi circumflex tilde 0x00AF, 0x02D8, 0x02D9, 0x02DA, // macron breve dotaccent ring 0x00B8, 0x02DD, 0x02DB, 0x02C7 // cedilla hungarumlaut ogonek caron }; Name::Name(const String &s, ErrorHandler *errh) : _str(s) { _str.align(2); _error = parse_header(errh ? errh : ErrorHandler::silent_handler()); } int Name::parse_header(ErrorHandler *errh) { // HEADER FORMAT: // USHORT version // USHORT numTables int len = _str.length(); const uint8_t *data = _str.udata(); if (len == 0) return errh->error("font has no % table"), -EFAULT; if (HEADER_SIZE > len) return errh->error("% table too small"), -EFAULT; if (!(data[0] == '\000' && data[1] == '\000')) return errh->error("bad % version number"), -ERANGE; int count = USHORT_AT(data + 2); if (HEADER_SIZE + count*NAMEREC_SIZE > len) return errh->error("% table too small"), -EFAULT; return 0; } String Name::name(const_iterator i) const { if (i < end()) { int stringOffset = USHORT_AT(_str.udata() + 4); int length = USHORT_AT(reinterpret_cast(i) + 8); int offset = USHORT_AT(reinterpret_cast(i) + 10); if (stringOffset + offset + length <= _str.length()) return _str.substring(stringOffset + offset, length); } return String(); } String Name::utf8_name(const_iterator i) const { // This code can handle Microsoft Unicode BMP and Mac Roman encodings, // but that's it if (!(i < end())) return String(); int stringOffset = USHORT_AT(_str.udata() + 4); int length = USHORT_AT(reinterpret_cast(i) + 8); int offset = USHORT_AT(reinterpret_cast(i) + 10); if (stringOffset + offset + length > _str.length()) return String(); const unsigned char *begins = _str.udata() + stringOffset + offset; const unsigned char *ends = begins + length; if (platform(*i) == P_MICROSOFT && encoding(*i) == E_MS_UNICODE_BMP) { StringAccum sa; for (const unsigned char *s = begins; s + 1 < ends; s += 2) sa.append_utf8(Data::u16(s)); return sa.take_string(); } else if (platform(*i) == P_MACINTOSH && encoding(*i) == E_MAC_ROMAN) { StringAccum sa; for (const unsigned char *s = begins; s < ends; s++) if (*s >= 0x80) { sa.append(begins, s); sa.append_utf8(mac_roman_encoding[*s & 0x7F]); begins = s + 1; } if (!sa) return _str.substring(begins, ends); else { sa.append(begins, ends); return sa.take_string(); } } else return _str.substring(begins, ends); } String Name::english_name(int nameid) const { const_iterator end = this->end(); const_iterator it = std::find_if(begin(), end, PlatformPred(nameid, P_MICROSOFT, E_MS_UNICODE_BMP, L_MS_ENGLISH_AMERICAN)); if (it == end) it = std::find_if(begin(), end, PlatformPred(nameid, P_MACINTOSH, E_MAC_ROMAN, 0)); return utf8_name(it); } bool Name::version_chaincontext_reverse_backtrack() const { String vstr = name(std::find_if(begin(), end(), PlatformPred(N_VERSION, 1, 0, 0))); const char *v = vstr.begin(), *endv = vstr.end(); if (v + 20 <= endv) { if (v[0] != 'O' || v[1] != 'T' || v[2] != 'F' || v[3] == ';') goto try_core; for (v += 4; v < endv && *v != ';'; v++) /* do nothing */; if (v + 3 >= endv || v[1] != 'P' || v[2] != 'S' || v[3] == ';') goto try_core; for (v += 4; v < endv && *v != ';'; v++) /* do nothing */; if (v + 11 >= endv || memcmp(v + 1, "Core 1.0.", 9) != 0 || (v[10] != '2' && v[10] != '3') || (v[11] < '0' || v[11] > '9')) goto try_core; return true; } try_core: v = vstr.begin(); if (v + 16 > endv || v[0] != 'C' || v[1] != 'o' || v[2] != 'r' || v[3] != 'e') return false; for (v += 4; v < endv && *v != ';'; v++) /* do nothing */; if (v + 12 > endv || memcmp(v, ";makeotf.lib", 12) != 0) return false; return true; } } // namespace Efont::OpenType } // namespace Efont lcdf-typetools-2.108/liblcdf/0000755000175000017500000000000013423377072013104 500000000000000lcdf-typetools-2.108/liblcdf/slurper.cc0000644000175000017500000001077213423375327015037 00000000000000// -*- related-file-name: "../include/lcdf/slurper.hh" -*- /* slurper.{cc,hh} -- reading from files a line at a time * * Copyright (c) 1998-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include static const int DefChunkCap = 2048; static const int WorthMoving = 256; Slurper::Slurper(const Filename &filename, FILE *f) : _filename(filename), _lineno(0), _data(new unsigned char[DefChunkCap]), _cap(DefChunkCap), _pos(0), _len(0), _line(0), _line_len(0), _saved_line(false), _at_eof(false) { if (f) { _f = f; _own_f = false; } else { _f = _filename.open_read(); _own_f = true; } } Slurper::~Slurper() { delete[] _data; if (_f && _own_f) fclose(_f); } void Slurper::grow_buffer() { // If we need to keep the upper part of the buffer, shift it down (moving // any data we care about). if (_pos >= _cap - WorthMoving) { // I used to move it myself, with a comment that SunOS didn't have a // correct implementation of memmove. This should be detected by // configure, if it's really a problem. memmove(_data, _data + _pos, _len - _pos); _len -= _pos; _pos = 0; } // Grow the buffer if necessary. if (_len >= _cap) { unsigned char *new_data = new unsigned char[ 2 * _cap ]; // I can't believe I didn't have the line below!! memcpy(new_data, _data, _len); delete[] _data; _data = new_data; _cap = 2 * _cap; } } inline int Slurper::more_data() { grow_buffer(); // Read new data into the buffer. int amount = fread(_data + _len, 1, _cap - _len, _f); _len += amount; return amount; } char * Slurper::get_line_at(unsigned pos) { while (1) { for (; pos < _len; pos++) if (_data[pos] == '\n' || _data[pos] == '\r') goto line_ends_at_pos; // no line end? look for more data. save and reset `pos', since _pos // may change. int offset = pos - _pos; bool got_more_data = more_data() != 0; pos = _pos + offset; if (!got_more_data) { _at_eof = true; goto line_ends_at_pos; } } line_ends_at_pos: // PRECONDITION: the line starts at _pos and ends at pos. unsigned next_pos; // Find beginning of next line. 3 cases: // 1. line ends in \r\n -> _pos = pos + 2; // 2. line ends in \r OR \n -> _pos = pos + 1; // 3. neither -> must be last line in file; _pos = pos, // since pos == _len if (pos == _len) { // last line in file didn't end in `\n': must have no data left // ensure we have enough space for terminating nul if (pos == _cap) grow_buffer(); next_pos = pos; // if already at EOF, don't increment the line number if (pos == _pos) _lineno--; } else if (_data[pos] == '\n') next_pos = pos + 1; else { assert(_data[pos] == '\r'); // If `\r' is last char in buffer, `\n' might be next char. Must read more // data to check for it, or we'd report an empty line that didn't really // exist. if (pos == _len - 1) { // be careful about the possible shift of _pos and _len! int offset = pos - _pos; more_data(); pos = _pos + offset; } if (pos < _len - 1 && _data[pos + 1] == '\n') next_pos = pos + 2; else next_pos = pos + 1; } _line = _data + _pos; _line_len = pos - _pos; _data[pos] = 0; _pos = next_pos; _lineno++; return (char *)_line; } char * Slurper::next_line() { if (_saved_line) { _saved_line = false; return (char *)_line; } get_line_at(_pos); if (_line_len == 0 && _at_eof) _line = 0; return (char *)_line; } char * Slurper::peek_line() { next_line(); _saved_line = true; return (char *)_line; } char * Slurper::append_next_line() { unsigned delta = (_data + _pos) - (_line + _line_len); if (_len - _pos > _line_len) { memmove(_line + delta, _line, _line_len); _line += delta; } else { memmove(_data + _pos - delta, _data + _pos, _len - _pos); _pos -= delta; _len -= delta; } unsigned append_at = _pos; _pos = _line - _data; return get_line_at(append_at); } lcdf-typetools-2.108/liblcdf/globmatch.cc0000644000175000017500000000525213423375327015300 00000000000000// -*- related-file-name: "../include/lcdf/globmatch.hh" -*- /* globmatch.{cc,hh} -- glob_match() function for shell globbing * * Copyright (c) 2000-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include bool glob_match(const String& str, const String& pattern) { const char* sdata = str.data(); const char* pdata = pattern.data(); int slen = str.length(); int plen = pattern.length(); int spos = 0, ppos = 0; Vector glob_ppos, glob_spos1, glob_spos2; while (1) { while (ppos < plen) switch (pdata[ppos]) { case '?': if (spos >= slen) goto done; spos++; ppos++; break; case '*': glob_ppos.push_back(ppos + 1); glob_spos1.push_back(spos); glob_spos2.push_back(slen); spos = slen; ppos++; break; case '[': { if (spos >= slen) goto done; // find end of character class int p = ppos + 1; bool negated = false; if (p < plen && pdata[p] == '^') { negated = true; p++; } int first = p; if (p < plen && pdata[p] == ']') p++; while (p < plen && pdata[p] != ']') p++; if (p >= plen) // not a character class at all goto ordinary; // parse character class bool in = false; for (int i = first; i < p && !in; i++) { int c1 = pdata[i]; int c2 = c1; if (i < p - 2 && pdata[i+1] == '-') { c2 = pdata[i+2]; i += 2; } if (sdata[spos] >= c1 && sdata[spos] <= c2) in = true; } if ((negated && in) || (!negated && !in)) goto done; ppos = p + 1; spos++; break; } default: ordinary: if (spos >= slen || sdata[spos] != pdata[ppos]) goto done; spos++; ppos++; break; } done: if (spos == slen && ppos == plen) return true; while (glob_ppos.size() && glob_spos1.back() == glob_spos2.back()) { glob_ppos.pop_back(); glob_spos1.pop_back(); glob_spos2.pop_back(); } if (glob_ppos.size()) { glob_spos2.back()--; spos = glob_spos2.back(); ppos = glob_ppos.back(); } else return false; } } lcdf-typetools-2.108/liblcdf/error.cc0000644000175000017500000006514013423375507014473 00000000000000// -*- related-file-name: "../include/lcdf/error.hh" -*- /* * error.{cc,hh} -- flexible classes for error reporting * Eddie Kohler * * Copyright (c) 1999-2000 Massachusetts Institute of Technology * Copyright (c) 2001-2019 Eddie Kohler * Copyright (c) 2008 Meraki, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file. These conditions include: you must * preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #ifndef __KERNEL__ # include # if HAVE_UNISTD_H # include # endif #endif /** @file error.hh * @brief Flexible error handling classes. */ struct ErrorHandler::Conversion { String name; ConversionFunction hook; Conversion *next; }; static ErrorHandler::Conversion *error_items; const char ErrorHandler::e_abort[] = "<-999>"; const char ErrorHandler::e_fatal[] = "<-1>"; const char ErrorHandler::e_emergency[] = "<0>"; const char ErrorHandler::e_alert[] = "<1>"; const char ErrorHandler::e_critical[] = "<2>"; const char ErrorHandler::e_error[] = "<3>"; const char ErrorHandler::e_warning[] = "<4>"; const char ErrorHandler::e_warning_annotated[] = "<4>warning: "; const char ErrorHandler::e_notice[] = "<5>"; const char ErrorHandler::e_info[] = "<6>"; const char ErrorHandler::e_debug[] = "<7>"; const int ErrorHandler::ok_result = 0; const int ErrorHandler::error_result = -EINVAL; ErrorHandler *ErrorHandler::the_default_handler = 0; ErrorHandler *ErrorHandler::the_silent_handler = 0; // ANNOTATION MANAGEMENT static const char * parse_level(const char *begin, const char *end, int *result) { int x = 0; const char *s = begin; bool negative = false; if (s != end && *s == '-') { negative = true; ++s; } else if (s != end && *s == '+') ++s; const char *digits = s; for (; s != end && *s >= '0' && *s <= '9'; ++s) x = x * 10 + *s - '0'; if (s != end && *s == '.') for (++s; s != end && *s >= '0' && *s <= '9'; ++s) /* nada */; if (s == digits || (s == digits + 1 && s[-1] == '.')) return begin; if (result) *result = (negative ? -x : x); return s; } String ErrorHandler::make_anno(const char *name, const String &value) { StringAccum sa; sa.reserve(value.length() + 10); // level annotation requires special handling if (name[0] == '<' && name[1] == '>' && name[2] == 0) { if (parse_level(value.begin(), value.end(), 0) == value.end()) { sa << '<' << value << '>'; return sa.take_string(); } else return String(); } sa << '{' << name << ':'; const char *last = value.begin(), *end = value.end(); for (const char *s = value.begin(); s != end; ++s) if (*s == '\\' || *s == '}') { sa.append(last, s); sa << '\\' << *s; last = s + 1; } else if (*s == '\n') { sa.append(last, s); sa << '\\' << 'n'; last = s + 1; } sa.append(last, end); sa << '}'; return sa.take_string(); } const char * ErrorHandler::skip_anno(const String &str, const char *begin, const char *end, String *name_result, String *value_result, bool raw) { String name, value; const char *s = begin; if (s + 3 <= end && *s == '<') { const char *x = parse_level(s + 1, end, 0); if (x != s + 1 && x != end && *x == '>') { name = String::make_stable("<>", 2); if (str) value = str.substring(begin + 1, x); begin = x + 1; } } else if (s + 2 <= end && *s == '{' && s[1] == '}') begin = s + 2; else if (s + 3 <= end && *s == '{' && str) { for (++s; s != end && isalnum((unsigned char) *s); ++s) /* nada */; if (s == end || s == begin + 1 || (*s != '}' && *s != ':')) /* not an annotation */; else if (*s == '}' && str) { name = str.substring(begin + 1, s); begin = s + 1; } else if (*s == '}') { name = String::make_stable("{}", 2); begin = s + 1; } else if (str) { const char *x, *last = s + 1; StringAccum sa; for (x = s + 1; x != end && *x != '\n' && *x != '}'; ++x) if (*x == '\\' && x + 1 != end && x[1] != '\n') { if (!raw) { sa.append(last, x); sa << (x[1] == 'n' ? '\n' : x[1]); last = x + 2; } ++x; } if (x != end && *x == '}') { name = str.substring(begin + 1, s); if (sa) { sa.append(last, x); value = sa.take_string(); } else value = str.substring(s + 1, x); begin = x + 1; } } else { const char *x; for (x = s + 1; x != end && *x != '\n' && *x != '}'; ++x) if (*x == '\\' && x + 1 != end && x[1] != '\n') ++x; if (x != end && *x == '}') { name = String::make_stable("{}", 2); begin = x + 1; } } } if (name_result) *name_result = name; if (value_result) *value_result = value; return begin; } const char * ErrorHandler::parse_anno(const String &str, const char *begin, const char *end, ...) { const char *names[8]; void *values[8]; int nanno = 0; va_list val; va_start(val, end); while (const char *n = va_arg(val, const char *)) { assert(nanno < 8); names[nanno] = n; if (n[0] == '#') values[nanno] = va_arg(val, int *); else values[nanno] = va_arg(val, String *); ++nanno; } String name, value; while (1) { begin = skip_anno(str, begin, end, &name, &value, false); if (!name) break; for (int i = 0; i < nanno; ++i) if (names[i][0] == '#') { if (name == (names[i] + 1)) parse_level(value.begin(), value.end(), (int *) values[i]); } else { if (name == names[i]) *(String *) values[i] = value; } } return begin; } String ErrorHandler::combine_anno(const String &text, const String &anno) { if (!anno) return text; String names[8], values[8]; int nanno = 0; const char *abegin = anno.begin(); while (abegin != anno.end()) { assert(nanno < 8); abegin = skip_anno(anno, abegin, anno.end(), &names[nanno], &values[nanno], true); if (names[nanno]) ++nanno; else break; } const char *last = text.begin(), *s = last; String name; StringAccum sa; while (s != text.end()) { const char *line = s; uint32_t mask = (1U << nanno) - 1; while (1) { s = skip_anno(text, s, text.end(), &name, 0, false); if (!name) break; for (int i = 0; i < nanno; ++i) if (name == names[i]) mask &= ~(1U << i); } if (mask) { sa.append(last, line); for (int i = 0; i < nanno; ++i) if (mask & (1U << i)) { if (names[i].equals("<>", 2)) sa << '<' << values[i] << '>'; else sa << '{' << names[i] << ':' << values[i] << '}'; } last = line; } if (abegin != anno.end()) { sa.append(last, s); sa.append(abegin, anno.end()); last = s; } while (s != text.end() && *s != '\n') ++s; if (s != text.end()) ++s; } if (sa) { sa.append(last, text.end()); return sa.take_string(); } else return text; } String ErrorHandler::clean_landmark(const String &landmark, bool with_colon) { const char *end = landmark.end(); while (end != landmark.begin() && isspace((unsigned char) end[-1])) --end; if (end != landmark.begin() && end[-1] == ':') --end; if (end == landmark.begin()) return String(); else if (with_colon) return landmark.substring(landmark.begin(), end) + ": "; else return landmark.substring(landmark.begin(), end); } // FORMATTING #define NUMBUF_SIZE 128 #define ErrH ErrorHandler #if SIZEOF_UNSIGNED_LONG >= SIZEOF_VOID_P typedef unsigned long do_number_t; #else typedef uintptr_t do_number_t; #endif static char* do_number(do_number_t num, char *after_last, int base, int flags) { const char *digits = ((flags & ErrH::cf_uppercase) ? "0123456789ABCDEF" : "0123456789abcdef"); char *pos = after_last; while (num) { *--pos = digits[num % base]; num /= base; } if (pos == after_last) *--pos = '0'; return pos; } static char * do_number_flags(char *pos, char *after_last, int base, int flags, int precision, int field_width) { // remove cf_alternate_form for zero results in base 16 if ((flags & ErrH::cf_alternate_form) && base == 16 && *pos == '0') flags &= ~ErrH::cf_alternate_form; // account for zero padding if (precision >= 0) while (after_last - pos < precision) *--pos = '0'; else if (flags & ErrH::cf_zero_pad) { if ((flags & ErrH::cf_alternate_form) && base == 16) field_width -= 2; if ((flags & ErrH::cf_negative) || (flags & (ErrH::cf_plus_positive | ErrH::cf_space_positive))) field_width--; while (after_last - pos < field_width) *--pos = '0'; } // alternate forms if ((flags & ErrH::cf_alternate_form) && base == 8 && pos[1] != '0') *--pos = '0'; else if ((flags & ErrH::cf_alternate_form) && base == 16) { *--pos = ((flags & ErrH::cf_uppercase) ? 'X' : 'x'); *--pos = '0'; } // sign if (flags & ErrH::cf_negative) *--pos = '-'; else if (flags & ErrH::cf_plus_positive) *--pos = '+'; else if (flags & ErrH::cf_space_positive) *--pos = ' '; return pos; } String ErrorHandler::vxformat(int default_flags, const char *s, va_list val) { StringAccum msg; char numbuf[NUMBUF_SIZE]; // for numerics numbuf[NUMBUF_SIZE-1] = 0; String strstore; // to ensure temporaries aren't destroyed // declare and initialize these here to make gcc shut up about possible // use before initialization int flags = 0; int field_width = -1; int precision = -1; int width_flag = 0; int base = 10; while (1) { const char *pct = strchr(s, '%'); if (!pct) { if (*s) msg << s; break; } if (pct != s) { msg.append(s, pct - s); s = pct; } // parse flags flags = default_flags; flags: switch (*++s) { case '#': flags |= cf_alternate_form; goto flags; case '0': flags |= cf_zero_pad; goto flags; case '-': flags |= cf_left_just; goto flags; case ' ': flags |= cf_space_positive; goto flags; case '+': flags |= cf_plus_positive; goto flags; case '\'': flags |= cf_singlequote; goto flags; case '_': flags &= ~cf_utf8; goto flags; } // parse field width field_width = -1; if (*s == '*') { field_width = va_arg(val, int); if (field_width < 0) { field_width = -field_width; flags |= cf_left_just; } s++; } else if (*s >= '0' && *s <= '9') for (field_width = 0; *s >= '0' && *s <= '9'; s++) field_width = 10*field_width + *s - '0'; // parse precision precision = -1; if (*s == '.') { s++; precision = 0; if (*s == '*') { precision = va_arg(val, int); s++; } else if (*s >= '0' && *s <= '9') for (; *s >= '0' && *s <= '9'; s++) precision = 10*precision + *s - '0'; } // parse width flags width_flag = 0; width_flags: switch (*s) { case 'h': case 'l': if (width_flag == *s) width_flag = *s + 'A' - 'a'; else if (width_flag) break; else width_flag = *s; s++; goto width_flags; case 'z': case 't': if (width_flag) break; width_flag = *s++; break; case '^': if (!isdigit((unsigned char) s[1]) || width_flag) break; for (s++; isdigit((unsigned char) *s); s++) width_flag = width_flag * 10 + *s - '0'; width_flag = -width_flag; break; } // conversion character // after switch, data lies between `s1' and `s2' const char *s1 = 0, *s2 = 0; base = 10; switch (*s++) { case 's': { s1 = va_arg(val, const char *); if (!s1) s1 = "(null)"; // fetch length int len; if (precision < 0) len = strlen(s1); else len = strnlen(s1, precision); // transform string if alternate form if (flags & cf_alternate_form) { strstore = String(s1, len).printable(); if (precision < 0 || strstore.length() < precision) len = strstore.length(); } // quote characters that look like annotations, readjusting length if (flags & (cf_singlequote | cf_alternate_form)) { if (!(flags & cf_alternate_form)) strstore = String(s1, len); // check first line, considering trailing part of 'msg' const char *mbegin = msg.end(); while (mbegin != msg.begin() && mbegin[-1] != '\n') --mbegin; if (skip_anno(strstore.begin(), strstore.end()) != strstore.begin() && skip_anno(mbegin, msg.end()) == msg.end()) { strstore = String::make_stable("{}", 2) + strstore; len += 2; } // check subsequent lines const char *s = std::find(strstore.begin(), strstore.end(), '\n'); while (s != strstore.end() && s + 1 != strstore.end()) { size_t nextpos = (s + 1) - strstore.begin(); if (skip_anno(s + 1, strstore.end()) != s + 1) { strstore = strstore.substring(strstore.begin(), s + 1) + String::make_stable("{}", 2) + strstore.substring(s + 1, strstore.end()); len += 2; } s = std::find(strstore.begin() + nextpos, strstore.end(), '\n'); } } // obtain begin and end pointers if (flags & (cf_singlequote | cf_alternate_form)) s1 = strstore.begin(); s2 = s1 + len; break; } case 'c': { int c = va_arg(val, int); // check for extension of 'signed char' to 'int' if (c < 0) c += 256; // assume ASCII if (c == '\n') strcpy(numbuf, "\\n"); else if (c == '\t') strcpy(numbuf, "\\t"); else if (c == '\r') strcpy(numbuf, "\\r"); else if (c == '\0') strcpy(numbuf, "\\0"); else if (c < 0 || c >= 256) strcpy(numbuf, "(bad char)"); else if (c < 32 || c >= 0177) sprintf(numbuf, "\\%03o", c); else sprintf(numbuf, "%c", c); s1 = numbuf; s2 = strchr(numbuf, 0); break; } case '%': { numbuf[0] = '%'; s1 = numbuf; s2 = s1 + 1; break; } case '<': s1 = (flags & cf_utf8 ? "\342\200\230" : "\'"); s2 = s1 + strlen(s1); break; case '>': case ',': s1 = (flags & cf_utf8 ? "\342\200\231" : "\'"); s2 = s1 + strlen(s1); break; case 'd': case 'i': flags |= cf_signed; /* fallthru */ case 'u': number: { // protect numbuf from overflow if (field_width > NUMBUF_SIZE) field_width = NUMBUF_SIZE; if (precision > NUMBUF_SIZE - 4) precision = NUMBUF_SIZE - 4; s2 = numbuf + NUMBUF_SIZE; do_number_t num; switch (width_flag) { case 'H': case -8: num = (unsigned char) va_arg(val, int); if ((flags & cf_signed) && (signed char) num < 0) num = -(signed char) num, flags |= cf_negative; break; case 'h': case -16: num = (unsigned short) va_arg(val, int); if ((flags & cf_signed) && (short) num < 0) num = -(short) num, flags |= cf_negative; break; case 0: case -32: #if SIZEOF_LONG == 4 case 'l': #endif #if SIZEOF_SIZE_T == 4 case 'z': #endif #if SIZEOF_PTRDIFF_T == 4 case 't': #endif num = va_arg(val, unsigned); if ((flags & cf_signed) && (int) num < 0) num = -(int) num, flags |= cf_negative; break; #if HAVE_INT64_TYPES # if SIZEOF_LONG == 8 case 'l': # endif # if SIZEOF_LONG_LONG == 8 case 'L': # endif # if SIZEOF_SIZE_T == 8 case 'z': # endif # if SIZEOF_PTRDIFF_T == 8 case 't': # endif case -64: { uint64_t qnum = va_arg(val, uint64_t); if ((flags & cf_signed) && (int64_t)qnum < 0) qnum = -(int64_t) qnum, flags |= cf_negative; StringAccum sa; sa.append_numeric(static_cast(qnum), base, (flags & cf_uppercase)); s1 = s2 - sa.length(); memcpy(const_cast(s1), sa.data(), s2 - s1); goto got_number; } #endif default: goto error; } s1 = do_number(num, (char*) s2, base, flags); #if HAVE_INT64_TYPES got_number: #endif s1 = do_number_flags((char*)s1, (char*) s2, base, flags, precision, field_width); break; } case 'o': base = 8; goto number; case 'X': flags |= cf_uppercase; /* fallthru */ case 'x': base = 16; goto number; case 'p': { if (*s == '{') { s1 = s2 = s + 1; while (*s2 && *s2 != '}' && !isspace((unsigned char) *s2)) ++s2; if (*s2 == '}') goto braces; } void* v = va_arg(val, void*); s2 = numbuf + NUMBUF_SIZE; s1 = do_number((do_number_t) v, (char*) s2, 16, flags); s1 = do_number_flags((char*) s1, (char*) s2, 16, flags | cf_alternate_form, precision, field_width); break; } #ifndef __KERNEL__ case 'e': case 'f': case 'g': case 'E': case 'F': case 'G': { char format[80], *f = format, new_numbuf[NUMBUF_SIZE]; *f++ = '%'; if (flags & cf_alternate_form) *f++ = '#'; if (precision >= 0) f += sprintf(f, ".%d", precision); *f++ = s[-1]; *f++ = 0; int len = sprintf(new_numbuf, format, va_arg(val, double)); s2 = numbuf + NUMBUF_SIZE; s1 = s2 - len; memcpy((char *)s1, new_numbuf, len); // note: no terminating \0 s1 = do_number_flags((char *)s1, (char *)s2, 10, flags & ~cf_alternate_form, -1, field_width); break; } #endif case '{': s1 = s2 = s; while (*s2 && *s2 != '}' && !isspace((unsigned char) *s2)) ++s2; if (*s2 != '}') goto error; goto braces; braces: s = s2 + 1; for (Conversion *item = error_items; item; item = item->next) if (item->name.equals(s1, s2 - s1)) { strstore = item->hook(flags, VA_LIST_REF(val)); s1 = strstore.begin(); s2 = strstore.end(); goto got_result; } goto error; error: default: assert(0 /* Bad % in error */); break; } // add result of conversion got_result: int slen = s2 - s1; if (slen > field_width) field_width = slen; char *dest = msg.extend(field_width); if (flags & cf_left_just) { memcpy(dest, s1, slen); memset(dest + slen, ' ', field_width - slen); } else { memcpy(dest + field_width - slen, s1, slen); memset(dest, (flags & cf_zero_pad ? '0' : ' '), field_width - slen); } } return msg.take_string(); } String ErrorHandler::xformat(int default_flags, const char *fmt, ...) { va_list val; va_start(val, fmt); String s = vxformat(default_flags, fmt, val); va_end(val); return s; } String ErrorHandler::xformat(const char *fmt, ...) { va_list val; va_start(val, fmt); String s = vxformat(0, fmt, val); va_end(val); return s; } String ErrorHandler::format(const char *fmt, ...) { va_list val; va_start(val, fmt); String s = vformat(fmt, val); va_end(val); return s; } // ERROR MESSAGE SHORTHAND void ErrorHandler::debug(const char *fmt, ...) { va_list val; va_start(val, fmt); xmessage(String::make_stable(e_debug, 3), fmt, val); va_end(val); } void ErrorHandler::message(const char *fmt, ...) { va_list val; va_start(val, fmt); xmessage(String::make_stable(e_info, 3), fmt, val); va_end(val); } int ErrorHandler::warning(const char *fmt, ...) { va_list val; va_start(val, fmt); int r = xmessage(String::make_stable(e_warning_annotated, 12), fmt, val); va_end(val); return r; } int ErrorHandler::error(const char *fmt, ...) { va_list val; va_start(val, fmt); int r = xmessage(String::make_stable(e_error, 3), fmt, val); va_end(val); return r; } void ErrorHandler::fatal(const char *fmt, ...) { va_list val; va_start(val, fmt); (void) xmessage(String::make_stable(e_fatal, 4), fmt, val); va_end(val); abort(); } void ErrorHandler::ldebug(const String &landmark, const char *fmt, ...) { va_list val; va_start(val, fmt); String l = make_landmark_anno(landmark); xmessage(String::make_stable(e_debug, 3) + l, fmt, val); va_end(val); } void ErrorHandler::lmessage(const String &landmark, const char *fmt, ...) { va_list val; va_start(val, fmt); String l = make_landmark_anno(landmark); xmessage(String::make_stable(e_info, 3) + l, fmt, val); va_end(val); } int ErrorHandler::lwarning(const String &landmark, const char *fmt, ...) { va_list val; va_start(val, fmt); String l = make_landmark_anno(landmark); int r = xmessage(l + String::make_stable(e_warning_annotated, 12), fmt, val); va_end(val); return r; } int ErrorHandler::lerror(const String &landmark, const char *fmt, ...) { va_list val; va_start(val, fmt); String l = make_landmark_anno(landmark); int r = xmessage(String::make_stable(e_error, 3) + l, fmt, val); va_end(val); return r; } void ErrorHandler::lfatal(const String &landmark, const char *fmt, ...) { va_list val; va_start(val, fmt); String l = make_landmark_anno(landmark); (void) xmessage(String::make_stable(e_fatal, 4) + l, fmt, val); va_end(val); abort(); } int ErrorHandler::xmessage(const String &str) { String xstr = decorate(str); int min_level = 1000, xlevel = 1000; const char *s = xstr.begin(), *end = xstr.end(); void *user_data = 0; while (s != end) { const char *l = parse_anno(xstr, s, end, "#<>", &xlevel, (const char *) 0); const char *nl = std::find(l, end, '\n'); String line = xstr.substring(s, nl); s = nl + (nl != end); user_data = emit(line, user_data, s != end); min_level = (xlevel < min_level ? xlevel : min_level); } account(min_level); return (min_level <= el_warning ? error_result : ok_result); } String ErrorHandler::vformat(const char *fmt, va_list val) { return vxformat(0, fmt, val); } String ErrorHandler::decorate(const String &str) { return str; } void * ErrorHandler::emit(const String &, void *user_data, bool) { return user_data; } void ErrorHandler::account(int level) { if (level <= el_error) ++_nerrors; #ifndef __KERNEL__ if (level <= el_abort) abort(); else if (level <= el_fatal) exit(-level); #endif } #ifndef __KERNEL__ // // FILE ERROR HANDLER // FileErrorHandler::FileErrorHandler(FILE *f, const String &context) : _f(f), _context(context), _default_flags(0) { # if HAVE_UNISTD_H if (isatty(fileno(_f))) { # endif char *s = getenv("LANG"); if (s && (strstr(s, "UTF-8") != 0 || strstr(s, "UTF8") != 0 || strstr(s, "utf8") != 0)) _default_flags |= cf_utf8; # if HAVE_UNISTD_H } # endif } String FileErrorHandler::vformat(const char *fmt, va_list val) { return vxformat(_default_flags, fmt, val); } void * FileErrorHandler::emit(const String &str, void *, bool) { String landmark; const char *s = parse_anno(str, str.begin(), str.end(), "l", &landmark, (const char *) 0); StringAccum sa; sa << _context << clean_landmark(landmark, true) << str.substring(s, str.end()) << '\n'; ssize_t result = fwrite(sa.begin(), 1, sa.length(), _f); (void) result; return 0; } #endif // // STATIC ERROR HANDLERS // ErrorHandler::Conversion * ErrorHandler::add_conversion(const String &name, ConversionFunction function) { if (Conversion *c = new Conversion) { c->name = name; c->hook = function; c->next = error_items; error_items = c; return c; } else return 0; } int ErrorHandler::remove_conversion(ErrorHandler::Conversion *conv) { Conversion **pprev = &error_items; for (Conversion *c = error_items; c; pprev = &c->next, c = *pprev) if (c == conv) { *pprev = c->next; delete c; return 0; } return -1; } ErrorHandler * ErrorHandler::static_initialize(ErrorHandler *default_handler) { if (!the_silent_handler) { the_default_handler = default_handler; the_silent_handler = new SilentErrorHandler; } return default_handler; } void ErrorHandler::static_cleanup() { delete the_default_handler; delete the_silent_handler; the_default_handler = the_silent_handler = 0; while (error_items) { Conversion *next = error_items->next; delete error_items; error_items = next; } } void ErrorHandler::set_default_handler(ErrorHandler *errh) { the_default_handler = errh; } // // ERROR VENEER // String ErrorVeneer::vformat(const char *fmt, va_list val) { if (_errh) return _errh->vformat(fmt, val); else return ErrorHandler::vformat(fmt, val); } String ErrorVeneer::decorate(const String &str) { if (_errh) return _errh->decorate(str); else return ErrorHandler::decorate(str); } void * ErrorVeneer::emit(const String &str, void *user_data, bool more) { if (_errh) return _errh->emit(str, user_data, more); else return ErrorHandler::emit(str, user_data, more); } void ErrorVeneer::account(int level) { ErrorHandler::account(level); if (_errh) _errh->account(level); } // // CONTEXT ERROR HANDLER // ContextErrorHandler::ContextErrorHandler(ErrorHandler *errh, const char *fmt, ...) : ErrorVeneer(errh), _indent(String::make_stable(" ", 2)), _context_landmark("{l:}"), _context_printed(false) { va_list val; va_start(val, fmt); _context = ErrorVeneer::vformat(fmt, val); va_end(val); if (_context) _context = combine_anno(_context, String::make_stable("{context:context}", 17)); } String ContextErrorHandler::decorate(const String &str) { String context_anno; const char *str_endanno = parse_anno(str, str.begin(), str.end(), "context", &context_anno, (const char *) 0); if (context_anno.equals("no", 2)) return ErrorVeneer::decorate(str); String istr; if (context_anno.equals("noindent", 8)) istr = combine_anno(str, _context_landmark); else istr = combine_anno(str, _context_landmark + _indent); if (!_context_printed && !context_anno.equals("nocontext", 9)) { String astr = combine_anno(combine_anno(_context, _context_landmark), str.substring(str.begin(), str_endanno)); if (astr && astr.back() != '\n') astr += '\n'; _context_printed = true; return ErrorVeneer::decorate(astr + istr); } else return ErrorVeneer::decorate(istr); } // // PREFIX ERROR HANDLER // PrefixErrorHandler::PrefixErrorHandler(ErrorHandler *errh, const String &prefix) : ErrorVeneer(errh), _prefix(prefix) { } String PrefixErrorHandler::decorate(const String &str) { return ErrorVeneer::decorate(combine_anno(str, _prefix)); } // // LANDMARK ERROR HANDLER // LandmarkErrorHandler::LandmarkErrorHandler(ErrorHandler *errh, const String &landmark) : ErrorVeneer(errh), _landmark(make_landmark_anno(landmark)) { } String LandmarkErrorHandler::decorate(const String &str) { return ErrorVeneer::decorate(combine_anno(str, _landmark)); } // // BAIL ERROR HANDLER // #ifndef __KERNEL__ BailErrorHandler::BailErrorHandler(ErrorHandler *errh, int l) : ErrorVeneer(errh), _level(l) { } void BailErrorHandler::account(int level) { ErrorVeneer::account(level); if (level <= _level) exit(1); } #endif lcdf-typetools-2.108/liblcdf/clp.c0000644000175000017500000020536313423375327013760 00000000000000/* -*- related-file-name: "../include/lcdf/clp.h" -*- */ /* clp.c - Complete source code for CLP. * This file is part of CLP, the command line parser package. * * Copyright (c) 1997-2019 Eddie Kohler, ekohler@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file, which is available in full at * http://www.pdos.lcs.mit.edu/click/license.html. The conditions include: you * must preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include /* By default, assume we have strtoul. */ #if !defined(HAVE_STRTOUL) && !defined(HAVE_CONFIG_H) # define HAVE_STRTOUL 1 #endif #ifdef __cplusplus extern "C" { #endif /** @file clp.h * @brief Functions for parsing command line options. * * The CLP functions are used to parse command line arugments into options. * It automatically handles value parsing, error messages, long options with * minimum prefix matching, short options, and negated options. * * The CLP model works like this. * *
    *
  1. The user declares an array of Clp_Option structures that define the * options their program accepts.
  2. *
  3. The user creates a Clp_Parser object using Clp_NewParser(), passing in * the command line arguments to parse and the Clp_Option structures.
  4. *
  5. A loop repeatedly calls Clp_Next() to parse the arguments.
  6. *
* * Unlike many command line parsing libraries, CLP steps through all arguments * one at a time, rather than slurping up all options at once. This makes it * meaningful to give an option more than once. * * Here's an example. * * @code * #define ANIMAL_OPT 1 * #define VEGETABLE_OPT 2 * #define MINERALS_OPT 3 * #define USAGE_OPT 4 * * static const Clp_Option options[] = { * { "animal", 'a', ANIMAL_OPT, Clp_ValString, 0 }, * { "vegetable", 'v', VEGETABLE_OPT, Clp_ValString, Clp_Negate | Clp_Optional }, * { "minerals", 'm', MINERALS_OPT, Clp_ValInt, 0 }, * { "usage", 0, USAGE_OPT, 0, 0 } * }; * * int main(int argc, char *argv[]) { * Clp_Parser *clp = Clp_NewParser(argc, argv, * sizeof(options) / sizeof(options[0]), options); * int opt; * while ((opt = Clp_Next(clp)) != Clp_Done) * switch (opt) { * case ANIMAL_OPT: * fprintf(stderr, "animal is %s\n", clp->val.s); * break; * case VEGETABLE_OPT: * if (clp->negated) * fprintf(stderr, "no vegetables!\n"); * else if (clp->have_val) * fprintf(stderr, "vegetable is %s\n", clp->val.s); * else * fprintf(stderr, "vegetables OK\n"); * break; * case MINERALS_OPT: * fprintf(stderr, "%d minerals\n", clp->val.i); * break; * case USAGE_OPT: * fprintf(stderr, "Usage: 20q [--animal=ANIMAL] [--vegetable[=VEGETABLE]] [--minerals=N]\n"); * break; * case Clp_NotOption: * fprintf(stderr, "non-option %s\n", clp->vstr); * break; * } * } * } * @endcode * * Here are a couple of executions. * *
 * % ./20q --animal=cat
 * animal is cat
 * % ./20q --animal=cat -a dog -afish --animal bird --an=snake
 * animal is cat
 * animal is dog
 * animal is fish
 * animal is bird
 * animal is snake
 * % ./20q --no-vegetables
 * no vegetables!
 * % ./20q -v
 * vegetables OK
 * % ./20q -vkale
 * vegetable is kale
 * % ./20q -m10
 * 10 minerals
 * % ./20q -m foo
 * '-m' expects an integer, not 'foo'
 * 
*/ /* Option types for Clp_SetOptionChar */ #define Clp_DoubledLong (Clp_LongImplicit * 2) #define Clp_InitialValType 8 #define MAX_AMBIGUOUS_VALUES 4 typedef struct { int val_type; Clp_ValParseFunc func; int flags; void *user_data; } Clp_ValType; typedef struct { unsigned ilong : 1; unsigned ishort : 1; unsigned imandatory : 1; unsigned ioptional : 1; unsigned ipos : 1; unsigned ineg : 1; unsigned iprefmatch : 1; unsigned lmmpos_short : 1; unsigned lmmneg_short : 1; unsigned char ilongoff; int lmmpos; int lmmneg; } Clp_InternOption; #define Clp_OptionCharsSize 5 typedef struct { int c; int type; } Clp_Oclass; #define Clp_OclassSize 10 typedef struct Clp_Internal { const Clp_Option *opt; Clp_InternOption *iopt; int nopt; unsigned opt_generation; Clp_ValType *valtype; int nvaltype; const char * const *argv; int argc; Clp_Oclass oclass[Clp_OclassSize]; int noclass; int long1pos; int long1neg; int utf8; char option_chars[Clp_OptionCharsSize]; const char *xtext; const char *program_name; void (*error_handler)(Clp_Parser *, const char *); int option_processing; int current_option; unsigned char is_short; unsigned char whole_negated; /* true if negated by an option character */ unsigned char could_be_short; unsigned char current_short; unsigned char negated_by_no; int ambiguous; int ambiguous_values[MAX_AMBIGUOUS_VALUES]; } Clp_Internal; struct Clp_ParserState { const char * const *argv; int argc; char option_chars[Clp_OptionCharsSize]; const char *xtext; int option_processing; unsigned opt_generation; int current_option; unsigned char is_short; unsigned char whole_negated; unsigned char current_short; unsigned char negated_by_no; }; typedef struct Clp_StringList { Clp_Option *items; Clp_InternOption *iopt; int nitems; int allow_int; int nitems_invalid_report; } Clp_StringList; static const Clp_Option clp_option_sentinel[] = { {"", 0, Clp_NotOption, 0, 0}, {"", 0, Clp_Done, 0, 0}, {"", 0, Clp_BadOption, 0, 0}, {"", 0, Clp_Error, 0, 0} }; static int parse_string(Clp_Parser *, const char *, int, void *); static int parse_int(Clp_Parser *, const char *, int, void *); static int parse_bool(Clp_Parser *, const char *, int, void *); static int parse_double(Clp_Parser *, const char *, int, void *); static int parse_string_list(Clp_Parser *, const char *, int, void *); static int ambiguity_error(Clp_Parser *, int, int *, const Clp_Option *, const Clp_InternOption *, const char *, const char *, ...); /******* * utf8 **/ #define U_REPLACEMENT 0xFFFD static char * encode_utf8(char *s, int n, int c) { if (c < 0 || c >= 0x110000 || (c >= 0xD800 && c <= 0xDFFF)) c = U_REPLACEMENT; if (c <= 0x7F && n >= 1) *s++ = c; else if (c <= 0x7FF && n >= 2) { *s++ = 0xC0 | (c >> 6); goto char1; } else if (c <= 0xFFFF && n >= 3) { *s++ = 0xE0 | (c >> 12); goto char2; } else if (n >= 4) { *s++ = 0xF0 | (c >> 18); *s++ = 0x80 | ((c >> 12) & 0x3F); char2: *s++ = 0x80 | ((c >> 6) & 0x3F); char1: *s++ = 0x80 | (c & 0x3F); } return s; } static int decode_utf8(const char *s, const char **cp) { int c; if ((unsigned char) *s <= 0x7F) /* 1 byte: 0x000000-0x00007F */ c = *s++; else if ((unsigned char) *s <= 0xC1) /* bad/overlong encoding */ goto replacement; else if ((unsigned char) *s <= 0xDF) { /* 2 bytes: 0x000080-0x0007FF */ if ((s[1] & 0xC0) != 0x80) /* bad encoding */ goto replacement; c = (*s++ & 0x1F) << 6; goto char1; } else if ((unsigned char) *s <= 0xEF) { /* 3 bytes: 0x000800-0x00FFFF */ if ((s[1] & 0xC0) != 0x80 /* bad encoding */ || (s[2] & 0xC0) != 0x80 /* bad encoding */ || ((unsigned char) *s == 0xE0 /* overlong encoding */ && (s[1] & 0xE0) == 0x80) || ((unsigned char) *s == 0xED /* encoded surrogate */ && (s[1] & 0xE0) == 0xA0)) goto replacement; c = (*s++ & 0x0F) << 12; goto char2; } else if ((unsigned char) *s <= 0xF4) { /* 4 bytes: 0x010000-0x10FFFF */ if ((s[1] & 0xC0) != 0x80 /* bad encoding */ || (s[2] & 0xC0) != 0x80 /* bad encoding */ || (s[3] & 0xC0) != 0x80 /* bad encoding */ || ((unsigned char) *s == 0xF0 /* overlong encoding */ && (s[1] & 0xF0) == 0x80) || ((unsigned char) *s == 0xF4 /* encoded value > 0x10FFFF */ && (unsigned char) s[1] >= 0x90)) goto replacement; c = (*s++ & 0x07) << 18; c += (*s++ & 0x3F) << 12; char2: c += (*s++ & 0x3F) << 6; char1: c += (*s++ & 0x3F); } else { replacement: c = U_REPLACEMENT; for (s++; (*s & 0xC0) == 0x80; s++) /* nothing */; } if (cp) *cp = s; return c; } static int utf8_charlen(const char *s) { const char *sout; (void) decode_utf8(s, &sout); return sout - s; } static int clp_utf8_charlen(const Clp_Internal *cli, const char *s) { return (cli->utf8 ? utf8_charlen(s) : 1); } /******* * Clp_NewParser, etc. **/ static int min_different_chars(const char *s, const char *t) /* Returns the minimum number of bytes required to distinguish s from t. If s is shorter than t, returns strlen(s). */ { const char *sfirst = s; while (*s && *t && *s == *t) s++, t++; if (!*s) return s - sfirst; else return s - sfirst + 1; } static int long_as_short(const Clp_Internal *cli, const Clp_Option *o, Clp_InternOption *io, int failure) { if ((cli->long1pos || cli->long1neg) && io->ilong) { const char *name = o->long_name + io->ilongoff; if (cli->utf8) { int c = decode_utf8(name, &name); if (!*name && c && c != U_REPLACEMENT) return c; } else if (name[0] && !name[1]) return (unsigned char) name[0]; } return failure; } static void compare_options(Clp_Parser *clp, const Clp_Option *o1, Clp_InternOption *io1, const Clp_Option *o2, Clp_InternOption *io2) { Clp_Internal *cli = clp->internal; int short1, shortx1; /* ignore meaningless combinations */ if ((!io1->ishort && !io1->ilong) || (!io2->ishort && !io2->ilong) || !((io1->ipos && io2->ipos) || (io1->ineg && io2->ineg)) || o1->option_id == o2->option_id) return; /* look for duplication of short options */ short1 = (io1->ishort ? o1->short_name : -1); shortx1 = long_as_short(cli, o1, io1, -2); if (short1 >= 0 || shortx1 >= 0) { int short2 = (io2->ishort ? o2->short_name : -3); int shortx2 = long_as_short(cli, o2, io2, -4); if (short1 == short2) Clp_OptionError(clp, "CLP internal error: more than 1 option has short name %<%c%>", short1); else if ((short1 == shortx2 || shortx1 == short2 || shortx1 == shortx2) && ((io1->ipos && io2->ipos && cli->long1pos) || (io1->ineg && io2->ineg && cli->long1neg))) Clp_OptionError(clp, "CLP internal error: 1-char long name conflicts with short name %<%c%>", (short1 == shortx2 ? shortx2 : shortx1)); } /* analyze longest minimum match */ if (io1->ilong) { const char *name1 = o1->long_name + io1->ilongoff; /* long name's first character matches short name */ if (io2->ishort && !io1->iprefmatch) { int name1char = (cli->utf8 ? decode_utf8(name1, 0) : (unsigned char) *name1); if (name1char == o2->short_name) { if (io1->ipos && io2->ipos) io1->lmmpos_short = 1; if (io1->ineg && io2->ineg) io1->lmmneg_short = 1; } } /* match long name to long name */ if (io2->ilong) { const char *name2 = o2->long_name + io2->ilongoff; if (strcmp(name1, name2) == 0) Clp_OptionError(clp, "CLP internal error: duplicate long name %<%s%>", name1); if (io1->ipos && io2->ipos && !strncmp(name1, name2, io1->lmmpos) && (!io1->iprefmatch || strncmp(name1, name2, strlen(name1)))) io1->lmmpos = min_different_chars(name1, name2); if (io1->ineg && io2->ineg && !strncmp(name1, name2, io1->lmmneg) && (!io1->iprefmatch || strncmp(name1, name2, strlen(name1)))) io1->lmmneg = min_different_chars(name1, name2); } } } static void calculate_lmm(Clp_Parser *clp, const Clp_Option *opt, Clp_InternOption *iopt, int nopt) { int i, j; for (i = 0; i < nopt; ++i) { iopt[i].lmmpos = iopt[i].lmmneg = 1; iopt[i].lmmpos_short = iopt[i].lmmneg_short = 0; for (j = 0; j < nopt; ++j) compare_options(clp, &opt[i], &iopt[i], &opt[j], &iopt[j]); } } /** @param argc number of arguments * @param argv argument array * @param nopt number of option definitions * @param opt option definition array * @return the parser * * The new Clp_Parser that will parse the arguments in @a argv according to * the option definitions in @a opt. * * The Clp_Parser is created with the following characteristics: * *
    *
  • The "-" character introduces short options (Clp_SetOptionChar(clp, * '-', Clp_Short)).
  • *
  • Clp_ProgramName is set from the first argument in @a argv, if any. The * first argument returned by Clp_Next() will be the second argument in @a * argv. Note that this behavior differs from Clp_SetArguments.
  • *
  • UTF-8 support is on iff the LANG environment variable contains * one of the substrings "UTF-8", "UTF8", or "utf8". Override this with * Clp_SetUTF8().
  • *
  • The Clp_ValString, Clp_ValStringNotOption, Clp_ValInt, Clp_ValUnsigned, * Clp_ValBool, and Clp_ValDouble types are installed.
  • *
  • Errors are reported to standard error.
  • *
* * You may also create a Clp_Parser with no arguments or options * (Clp_NewParser(0, 0, 0, 0)) and set the arguments and options * later. * * Returns NULL if there isn't enough memory to construct the parser. * * @note The CLP library will not modify the contents of @a argv or @a opt. * The calling program must not modify @a opt. It may modify @a argv in * limited cases. */ Clp_Parser * Clp_NewParser(int argc, const char * const *argv, int nopt, const Clp_Option *opt) { Clp_Parser *clp = (Clp_Parser *)malloc(sizeof(Clp_Parser)); Clp_Internal *cli = (Clp_Internal *)malloc(sizeof(Clp_Internal)); Clp_InternOption *iopt = (Clp_InternOption *)malloc(sizeof(Clp_InternOption) * nopt); if (cli) cli->valtype = (Clp_ValType *)malloc(sizeof(Clp_ValType) * Clp_InitialValType); if (!clp || !cli || !iopt || !cli->valtype) goto failed; clp->option = &clp_option_sentinel[-Clp_Done]; clp->negated = 0; clp->have_val = 0; clp->vstr = 0; clp->user_data = 0; clp->internal = cli; cli->opt = opt; cli->nopt = nopt; cli->iopt = iopt; cli->opt_generation = 0; cli->error_handler = 0; /* Assign program name (now so we can call Clp_OptionError) */ if (argc > 0) { const char *slash = strrchr(argv[0], '/'); cli->program_name = slash ? slash + 1 : argv[0]; } else cli->program_name = 0; /* Assign arguments, skipping program name */ Clp_SetArguments(clp, argc - 1, argv + 1); /* Initialize UTF-8 status and option classes */ { char *s = getenv("LANG"); cli->utf8 = (s && (strstr(s, "UTF-8") != 0 || strstr(s, "UTF8") != 0 || strstr(s, "utf8") != 0)); } cli->oclass[0].c = '-'; cli->oclass[0].type = Clp_Short; cli->noclass = 1; cli->long1pos = cli->long1neg = 0; /* Add default type parsers */ cli->nvaltype = 0; Clp_AddType(clp, Clp_ValString, 0, parse_string, 0); Clp_AddType(clp, Clp_ValStringNotOption, Clp_DisallowOptions, parse_string, 0); Clp_AddType(clp, Clp_ValInt, 0, parse_int, 0); Clp_AddType(clp, Clp_ValUnsigned, 0, parse_int, (void *)cli); Clp_AddType(clp, Clp_ValBool, 0, parse_bool, 0); Clp_AddType(clp, Clp_ValDouble, 0, parse_double, 0); /* Set options */ Clp_SetOptions(clp, nopt, opt); return clp; failed: if (cli && cli->valtype) free(cli->valtype); if (cli) free(cli); if (clp) free(clp); if (iopt) free(iopt); return 0; } /** @param clp the parser * * All memory associated with @a clp is freed. */ void Clp_DeleteParser(Clp_Parser *clp) { int i; Clp_Internal *cli; if (!clp) return; cli = clp->internal; /* get rid of any string list types */ for (i = 0; i < cli->nvaltype; i++) if (cli->valtype[i].func == parse_string_list) { Clp_StringList *clsl = (Clp_StringList *)cli->valtype[i].user_data; free(clsl->items); free(clsl->iopt); free(clsl); } free(cli->valtype); free(cli->iopt); free(cli); free(clp); } /** @param clp the parser * @param errh error handler function * @return previous error handler function * * The error handler function is called when CLP encounters an error while * parsing the command line. It is called with the arguments "(*errh)(@a * clp, s)", where s is a description of the error terminated by * a newline. The s descriptions produced by CLP itself are prefixed * by the program name, if any. */ Clp_ErrorHandler Clp_SetErrorHandler(Clp_Parser *clp, void (*errh)(Clp_Parser *, const char *)) { Clp_Internal *cli = clp->internal; Clp_ErrorHandler old = cli->error_handler; cli->error_handler = errh; return old; } /** @param clp the parser * @param utf8 does the parser support UTF-8? * @return previous UTF-8 mode * * In UTF-8 mode, all input strings (arguments and long names for options) are * assumed to be encoded via UTF-8, and all character names * (Clp_SetOptionChar() and short names for options) may cover the whole * Unicode range. Out of UTF-8 mode, all input strings are treated as binary, * and all character names must be unsigned char values. * * Furthermore, error messages in UTF-8 mode may contain Unicode quote * characters. */ int Clp_SetUTF8(Clp_Parser *clp, int utf8) { Clp_Internal *cli = clp->internal; int old_utf8 = cli->utf8; cli->utf8 = utf8; calculate_lmm(clp, cli->opt, cli->iopt, cli->nopt); return old_utf8; } /** @param clp the parser * @param c character * @return option character treatment * * Returns an integer specifying how CLP treats arguments that begin * with character @a c. See Clp_SetOptionChar for possibilities. */ int Clp_OptionChar(Clp_Parser *clp, int c) { Clp_Internal *cli = clp->internal; int i, oclass = 0; if (cli->noclass > 0 && cli->oclass[0].c == 0) oclass = cli->oclass[0].type; for (i = 0; i < cli->noclass; ++i) if (cli->oclass[i].c == c) oclass = cli->oclass[i].type; return oclass; } /** @param clp the parser * @param c character * @param type option character treatment * @return previous option character treatment, or -1 on error * * @a type specifies how CLP treats arguments that begin with character @a c. * Possibilities are: * *
*
Clp_NotOption (or 0)
*
The argument cannot be an option.
*
Clp_Long
*
The argument is a long option.
*
Clp_Short
*
The argument is a set of short options.
*
Clp_Short|Clp_Long
*
The argument is either a long option or, if no matching long option is * found, a set of short options.
*
Clp_LongNegated
*
The argument is a negated long option. For example, after * Clp_SetOptionChar(@a clp, '^', Clp_LongNegated), the argument "^foo" is * equivalent to "--no-foo".
*
Clp_ShortNegated
*
The argument is a set of negated short options.
*
Clp_ShortNegated|Clp_LongNegated
*
The argument is either a negated long option or, if no matching long * option is found, a set of negated short options.
*
Clp_LongImplicit
*
The argument may be a long option, where the character @a c is actually * part of the long option name. For example, after Clp_SetOptionChar(@a clp, * 'f', Clp_LongImplicit), the argument "foo" may be equivalent to * "--foo".
*
* * In UTF-8 mode, @a c may be any Unicode character. Otherwise, @a c must be * an unsigned char value. The special character 0 assigns @a type to @em * every character. * * It is an error if @a c is out of range, @a type is illegal, or there are * too many character definitions stored in @a clp already. The function * returns -1 on error. * * A double hyphen "--" always introduces a long option. This behavior cannot * currently be changed with Clp_SetOptionChar(). */ int Clp_SetOptionChar(Clp_Parser *clp, int c, int type) { int i, long1pos, long1neg; int old = Clp_OptionChar(clp, c); Clp_Internal *cli = clp->internal; if (type != Clp_NotOption && type != Clp_Short && type != Clp_Long && type != Clp_ShortNegated && type != Clp_LongNegated && type != Clp_LongImplicit && type != (Clp_Short | Clp_Long) && type != (Clp_ShortNegated | Clp_LongNegated)) return -1; if (c < 0 || c >= (cli->utf8 ? 0x110000 : 256)) return -1; if (c == 0) cli->noclass = 0; for (i = 0; i < cli->noclass; ++i) if (cli->oclass[i].c == c) break; if (i == Clp_OclassSize) return -1; cli->oclass[i].c = c; cli->oclass[i].type = type; if (cli->noclass == i) cli->noclass = i + 1; long1pos = long1neg = 0; for (i = 0; i < cli->noclass; ++i) { if ((cli->oclass[i].type & Clp_Short) && (cli->oclass[i].type & Clp_Long)) long1pos = 1; if ((cli->oclass[i].type & Clp_ShortNegated) && (cli->oclass[i].type & Clp_LongNegated)) long1neg = 1; } if (long1pos != cli->long1pos || long1neg != cli->long1neg) { /* Must recheck option set */ cli->long1pos = long1pos; cli->long1neg = long1neg; calculate_lmm(clp, cli->opt, cli->iopt, cli->nopt); } return old; } /** @param clp the parser * @param nopt number of option definitions * @param opt option definition array * @return 0 on success, -1 on failure * * Installs the option definitions in @a opt. Future option parsing will * use @a opt to search for options. * * Also checks @a opt's option definitions for validity. "CLP internal * errors" are reported via Clp_OptionError() if: * *
    *
  • An option has a negative ID.
  • *
  • Two different short options have the same name.
  • *
  • Two different long options have the same name.
  • *
  • A short and a long option are ambiguous, in that some option character * might introduce either a short or a long option (e.g., Clp_SetOptionChar(@a * clp, '-', Clp_Long|Clp_Short)), and a short name equals a long name.
  • *
* * If necessary memory cannot be allocated, this function returns -1 without * modifying the parser. * * @note The CLP library will not modify the contents of @a argv or @a opt. * The calling program must not modify @a opt either until another call to * Clp_SetOptions() or the parser is destroyed. */ int Clp_SetOptions(Clp_Parser *clp, int nopt, const Clp_Option *opt) { Clp_Internal *cli = clp->internal; Clp_InternOption *iopt; int i; static unsigned opt_generation = 0; if (nopt > cli->nopt) { iopt = (Clp_InternOption *)malloc(sizeof(Clp_InternOption) * nopt); if (!iopt) return -1; free(cli->iopt); cli->iopt = iopt; } cli->opt = opt; cli->nopt = nopt; cli->opt_generation = ++opt_generation; iopt = cli->iopt; cli->current_option = -1; /* Massage the options to make them usable */ for (i = 0; i < nopt; i++) { /* Ignore negative option_ids, which are internal to CLP */ if (opt[i].option_id < 0) { Clp_OptionError(clp, "CLP internal error: option %d has negative option_id", i); iopt[i].ilong = iopt[i].ishort = iopt[i].ipos = iopt[i].ineg = 0; continue; } /* Set flags based on input flags */ iopt[i].ilong = (opt[i].long_name != 0 && opt[i].long_name[0] != 0); iopt[i].ishort = (opt[i].short_name > 0 && opt[i].short_name < (cli->utf8 ? 0x110000 : 256)); iopt[i].ipos = 1; iopt[i].ineg = (opt[i].flags & Clp_Negate) != 0; iopt[i].imandatory = (opt[i].flags & Clp_Mandatory) != 0; iopt[i].ioptional = (opt[i].flags & Clp_Optional) != 0; iopt[i].iprefmatch = (opt[i].flags & Clp_PreferredMatch) != 0; iopt[i].ilongoff = 0; /* Enforce invariants */ if (opt[i].val_type <= 0) iopt[i].imandatory = iopt[i].ioptional = 0; if (opt[i].val_type > 0 && !iopt[i].ioptional) iopt[i].imandatory = 1; /* Options that start with 'no-' should be changed to OnlyNegated */ if (iopt[i].ilong && strncmp(opt[i].long_name, "no-", 3) == 0) { iopt[i].ipos = 0; iopt[i].ineg = 1; iopt[i].ilongoff = 3; if (strncmp(opt[i].long_name + 3, "no-", 3) == 0) Clp_OptionError(clp, "CLP internal error: option %d begins with \"no-no-\"", i); } else if (opt[i].flags & Clp_OnlyNegated) { iopt[i].ipos = 0; iopt[i].ineg = 1; } } /* Check option set */ calculate_lmm(clp, opt, iopt, nopt); return 0; } /** @param clp the parser * @param argc number of arguments * @param argv argument array * * Installs the arguments in @a argv for parsing. Future option parsing will * analyze @a argv. * * Unlike Clp_NewParser(), this function does not treat @a argv[0] specially. * The first subsequent call to Clp_Next() will analyze @a argv[0]. * * This function also sets option processing to on, as by * Clp_SetOptionProcessing(@a clp, 1). * * @note The CLP library will not modify the contents of @a argv. The calling * program should not generally modify the element of @a argv that CLP is * currently analyzing. */ void Clp_SetArguments(Clp_Parser *clp, int argc, const char * const *argv) { Clp_Internal *cli = clp->internal; cli->argc = argc + 1; cli->argv = argv - 1; cli->is_short = 0; cli->whole_negated = 0; cli->option_processing = 1; cli->current_option = -1; } /** @param clp the parser * @param on whether to search for options * @return previous option processing setting * * When option processing is off, every call to Clp_Next() returns * Clp_NotOption. By default the option "--" turns off option * processing and is otherwise ignored. */ int Clp_SetOptionProcessing(Clp_Parser *clp, int on) { Clp_Internal *cli = clp->internal; int old = cli->option_processing; cli->option_processing = on; return old; } /******* * functions for Clp_Option lists **/ /* the ever-glorious argcmp */ static int argcmp(const char *ref, const char *arg, int min_match, int fewer_dashes) /* Returns 0 if ref and arg don't match. Returns -1 if ref and arg match, but fewer than min_match characters. Returns len if ref and arg match min_match or more characters; len is the number of characters that matched in arg. Allows arg to contain fewer dashes than ref iff fewer_dashes != 0. Examples: argcmp("x", "y", 1, 0) --> 0 / just plain wrong argcmp("a", "ax", 1, 0) --> 0 / ...even though min_match == 1 and the 1st chars match argcmp("box", "bo", 3, 0) --> -1 / ambiguous argcmp("cat", "c=3", 1, 0) --> 1 / handles = arguments */ { const char *refstart = ref; const char *argstart = arg; assert(min_match > 0); compare: while (*ref && *arg && *arg != '=' && *ref == *arg) ref++, arg++; /* Allow arg to contain fewer dashes than ref */ if (fewer_dashes && *ref == '-' && ref[1] && ref[1] == *arg) { ref++; goto compare; } if (*arg && *arg != '=') return 0; else if (ref - refstart < min_match) return -1; else return arg - argstart; } static int find_prefix_opt(Clp_Parser *clp, const char *arg, int nopt, const Clp_Option *opt, const Clp_InternOption *iopt, int *ambiguous, int *ambiguous_values) /* Looks for an unambiguous match of 'arg' against one of the long options in 'opt'. Returns positive if it finds one; otherwise, returns -1 and possibly changes 'ambiguous' and 'ambiguous_values' to keep track of at most MAX_AMBIGUOUS_VALUES possibilities. */ { int i, fewer_dashes = 0, first_ambiguous = *ambiguous; int negated = clp && clp->negated; int first_charlen = (clp ? clp_utf8_charlen(clp->internal, arg) : 1); retry: for (i = 0; i < nopt; i++) { int len, lmm; if (!iopt[i].ilong || (negated ? !iopt[i].ineg : !iopt[i].ipos)) continue; lmm = (negated ? iopt[i].lmmneg : iopt[i].lmmpos); if (clp && clp->internal->could_be_short && (negated ? iopt[i].lmmneg_short : iopt[i].lmmpos_short)) lmm = (first_charlen >= lmm ? first_charlen + 1 : lmm); len = argcmp(opt[i].long_name + iopt[i].ilongoff, arg, lmm, fewer_dashes); if (len > 0) return i; else if (len < 0) { if (*ambiguous < MAX_AMBIGUOUS_VALUES) ambiguous_values[*ambiguous] = i; (*ambiguous)++; } } /* If there were no partial matches, try again with fewer_dashes true */ if (*ambiguous == first_ambiguous && !fewer_dashes) { fewer_dashes = 1; goto retry; } return -1; } /***** * Argument parsing **/ static int val_type_binsearch(Clp_Internal *cli, int val_type) { unsigned l = 0, r = cli->nvaltype; while (l < r) { unsigned m = l + (r - l) / 2; if (cli->valtype[m].val_type == val_type) return m; else if (cli->valtype[m].val_type < val_type) l = m + 1; else r = m; } return l; } /** @param clp the parser * @param val_type value type ID * @param flags value type flags * @param parser parser function * @param user_data user data for @a parser function * @return 0 on success, -1 on failure * * Defines argument type @a val_type in parser @a clp. The parsing function * @a parser will be passed argument values for type @a val_type. It should * parse the argument into values (usually in @a clp->val, but sometimes * elsewhere), report errors if necessary, and return whether the parse was * successful. * * Any prior argument parser match @a val_type is removed. @a val_type must * be greater than zero. * * @a flags specifies additional parsing flags. At the moment the only * relevant flag is Clp_DisallowOptions, which means that separated values * must not look like options. For example, assume argument * --a/-a has mandatory value type Clp_ValStringNotOption * (which has Clp_DisallowOptions). Then: * *
    *
  • --a=--b will parse with value --b.
  • *
  • -a--b will parse with value --b.
  • *
  • --a --b will not parse, since the mandatory value looks like * an option.
  • *
  • -a --b will not parse, since the mandatory value looks like * an option.
  • *
*/ int Clp_AddType(Clp_Parser *clp, int val_type, int flags, Clp_ValParseFunc parser, void *user_data) { Clp_Internal *cli = clp->internal; int vtpos; if (val_type <= 0 || !parser) return -1; vtpos = val_type_binsearch(cli, val_type); if (vtpos == cli->nvaltype || cli->valtype[vtpos].val_type != val_type) { if (cli->nvaltype != 0 && (cli->nvaltype % Clp_InitialValType) == 0) { Clp_ValType *new_valtype = (Clp_ValType *) realloc(cli->valtype, sizeof(Clp_ValType) * (cli->nvaltype + Clp_InitialValType)); if (!new_valtype) return -1; cli->valtype = new_valtype; } memmove(&cli->valtype[vtpos + 1], &cli->valtype[vtpos], sizeof(Clp_ValType) * (cli->nvaltype - vtpos)); cli->nvaltype++; cli->valtype[vtpos].func = 0; } if (cli->valtype[vtpos].func == parse_string_list) { Clp_StringList *clsl = (Clp_StringList *) cli->valtype[vtpos].user_data; free(clsl->items); free(clsl->iopt); free(clsl); } cli->valtype[vtpos].val_type = val_type; cli->valtype[vtpos].func = parser; cli->valtype[vtpos].flags = flags; cli->valtype[vtpos].user_data = user_data; return 0; } /******* * Default argument parsers **/ static int parse_string(Clp_Parser *clp, const char *arg, int complain, void *user_data) { (void)complain, (void)user_data; clp->val.s = arg; return 1; } static int parse_int(Clp_Parser *clp, const char *arg, int complain, void *user_data) { const char *val; if (*arg == 0 || isspace((unsigned char) *arg) || (user_data != 0 && *arg == '-')) val = arg; else if (user_data != 0) { /* unsigned */ #if HAVE_STRTOUL clp->val.u = strtoul(arg, (char **) &val, 0); #else /* don't bother really trying to do it right */ if (arg[0] == '-') val = arg; else clp->val.u = strtol(arg, (char **) &val, 0); #endif } else clp->val.i = strtol(arg, (char **) &val, 0); if (*arg != 0 && *val == 0) return 1; else if (complain) { const char *message = user_data != 0 ? "%<%O%> expects a nonnegative integer, not %<%s%>" : "%<%O%> expects an integer, not %<%s%>"; return Clp_OptionError(clp, message, arg); } else return 0; } static int parse_double(Clp_Parser *clp, const char *arg, int complain, void *user_data) { const char *val; (void)user_data; if (*arg == 0 || isspace((unsigned char) *arg)) val = arg; else clp->val.d = strtod(arg, (char **) &val); if (*arg != 0 && *val == 0) return 1; else if (complain) return Clp_OptionError(clp, "%<%O%> expects a real number, not %<%s%>", arg); else return 0; } static int parse_bool(Clp_Parser *clp, const char *arg, int complain, void *user_data) { int i; char lcarg[6]; (void)user_data; if (strlen(arg) > 5 || strchr(arg, '=') != 0) goto error; for (i = 0; arg[i] != 0; i++) lcarg[i] = tolower((unsigned char) arg[i]); lcarg[i] = 0; if (argcmp("yes", lcarg, 1, 0) > 0 || argcmp("true", lcarg, 1, 0) > 0 || argcmp("1", lcarg, 1, 0) > 0) { clp->val.i = 1; return 1; } else if (argcmp("no", lcarg, 1, 0) > 0 || argcmp("false", lcarg, 1, 0) > 0 || argcmp("1", lcarg, 1, 0) > 0) { clp->val.i = 0; return 1; } error: if (complain) Clp_OptionError(clp, "%<%O%> expects a true-or-false value, not %<%s%>", arg); return 0; } /***** * Clp_AddStringListType **/ static int parse_string_list(Clp_Parser *clp, const char *arg, int complain, void *user_data) { Clp_StringList *sl = (Clp_StringList *)user_data; int idx, ambiguous = 0; int ambiguous_values[MAX_AMBIGUOUS_VALUES + 1]; /* actually look for a string value */ idx = find_prefix_opt (0, arg, sl->nitems, sl->items, sl->iopt, &ambiguous, ambiguous_values); if (idx >= 0) { clp->val.i = sl->items[idx].option_id; return 1; } if (sl->allow_int) { if (parse_int(clp, arg, 0, 0)) return 1; } if (complain) { const char *complaint = (ambiguous ? "ambiguous" : "invalid"); if (!ambiguous) { ambiguous = sl->nitems_invalid_report; for (idx = 0; idx < ambiguous; idx++) ambiguous_values[idx] = idx; } return ambiguity_error (clp, ambiguous, ambiguous_values, sl->items, sl->iopt, "", "option %<%O%> value %<%s%> is %s", arg, complaint); } else return 0; } static int finish_string_list(Clp_Parser *clp, int val_type, int flags, Clp_Option *items, int nitems, int itemscap) { int i; Clp_StringList *clsl = (Clp_StringList *)malloc(sizeof(Clp_StringList)); Clp_InternOption *iopt = (Clp_InternOption *)malloc(sizeof(Clp_InternOption) * nitems); if (!clsl || !iopt) goto error; clsl->items = items; clsl->iopt = iopt; clsl->nitems = nitems; clsl->allow_int = (flags & Clp_AllowNumbers) != 0; if (nitems < MAX_AMBIGUOUS_VALUES && nitems < itemscap && clsl->allow_int) { items[nitems].long_name = "any integer"; clsl->nitems_invalid_report = nitems + 1; } else if (nitems > MAX_AMBIGUOUS_VALUES + 1) clsl->nitems_invalid_report = MAX_AMBIGUOUS_VALUES + 1; else clsl->nitems_invalid_report = nitems; for (i = 0; i < nitems; i++) { iopt[i].ilong = iopt[i].ipos = 1; iopt[i].ishort = iopt[i].ineg = iopt[i].ilongoff = iopt[i].iprefmatch = 0; } calculate_lmm(clp, items, iopt, nitems); if (Clp_AddType(clp, val_type, 0, parse_string_list, clsl) >= 0) return 0; error: if (clsl) free(clsl); if (iopt) free(iopt); return -1; } /** @param clp the parser * @param val_type value type ID * @param flags string list flags * @return 0 on success, -1 on failure * * Defines argument type @a val_type in parser @a clp. The parsing function * sets @a clp->val.i to an integer. The value string is matched against * strings provided in the ellipsis arguments. For example, the * Clp_AddStringListType() call below has the same effect as the * Clp_AddStringListTypeVec() call: * * For example: * @code * Clp_AddStringListType(clp, 100, Clp_AllowNumbers, "cat", 1, * "cattle", 2, "dog", 3, (const char *) NULL); * * const char * const strs[] = { "cat", "cattle", "dog" }; * const int vals[] = { 1, 2, 3 }; * Clp_AddStringListTypeVec(clp, 100, Clp_AllowNumbers, 3, strs, vals); * @endcode * * @note The CLP library will not modify any of the passed-in strings. The * calling program must not modify or free them either until the parser is * destroyed. */ int Clp_AddStringListType(Clp_Parser *clp, int val_type, int flags, ...) { int nitems = 0; int itemscap = 5; Clp_Option *items = (Clp_Option *)malloc(sizeof(Clp_Option) * itemscap); va_list val; va_start(val, flags); if (!items) goto error; /* slurp up the arguments */ while (1) { int value; char *name = va_arg(val, char *); if (!name) break; value = va_arg(val, int); if (nitems >= itemscap) { Clp_Option *new_items; itemscap *= 2; new_items = (Clp_Option *)realloc(items, sizeof(Clp_Option) * itemscap); if (!new_items) goto error; items = new_items; } items[nitems].long_name = name; items[nitems].option_id = value; items[nitems].flags = 0; nitems++; } va_end(val); if (finish_string_list(clp, val_type, flags, items, nitems, itemscap) >= 0) return 0; error: va_end(val); if (items) free(items); return -1; } /** @param clp the parser * @param val_type value type ID * @param flags string list flags * @param nstrs number of strings in list * @param strs array of strings * @param vals array of values * @return 0 on success, -1 on failure * * Defines argument type @a val_type in parser @a clp. The parsing function * sets @a clp->val.i to an integer. The value string is matched against the * @a strs. If there's a unique match, the corresponding entry from @a vals * is returned. Unique prefix matches also work. Finally, if @a flags * contains the Clp_AllowNumbers flag, then integers are also accepted. * * For example: * @code * const char * const strs[] = { "cat", "cattle", "dog" }; * const int vals[] = { 1, 2, 3 }; * Clp_AddStringListTypeVec(clp, 100, Clp_AllowNumbers, 3, strs, vals); * @endcode * * Say that option --animal takes value type 100. Then: * *
    *
  • --animal=cat will succeed and set @a clp->val.i = 1.
  • *
  • --animal=cattle will succeed and set @a clp->val.i = 2.
  • *
  • --animal=dog will succeed and set @a clp->val.i = 3.
  • *
  • --animal=d will succeed and set @a clp->val.i = 3.
  • *
  • --animal=c will fail, since c is ambiguous.
  • *
  • --animal=4 will succeed and set @a clp->val.i = 4.
  • *
* * @note The CLP library will not modify the contents of @a strs or @a vals. * The calling program can modify the @a strs array, but the actual strings * (for instance, @a strs[0] and @a strs[1]) must not be modified or freed * until the parser is destroyed. */ int Clp_AddStringListTypeVec(Clp_Parser *clp, int val_type, int flags, int nstrs, const char * const *strs, const int *vals) /* An alternate way to make a string list type. See Clp_AddStringListType for the basics; this coalesces the strings and values into two arrays, rather than spreading them out into a variable argument list. */ { int i; int itemscap = (nstrs < 5 ? 5 : nstrs); Clp_Option *items = (Clp_Option *)malloc(sizeof(Clp_Option) * itemscap); if (!items) return -1; /* copy over items */ for (i = 0; i < nstrs; i++) { items[i].long_name = strs[i]; items[i].option_id = vals[i]; items[i].flags = 0; } if (finish_string_list(clp, val_type, flags, items, nstrs, itemscap) >= 0) return 0; else { free(items); return -1; } } /******* * Returning information **/ const char * Clp_ProgramName(Clp_Parser *clp) { return clp->internal->program_name; } /** @param clp the parser * @param name new program name * @return previous program name * * The calling program should not modify or free @a name until @a clp itself * is destroyed. */ const char * Clp_SetProgramName(Clp_Parser *clp, const char *name) { const char *old = clp->internal->program_name; clp->internal->program_name = name; return old; } /****** * Clp_ParserStates **/ /** @return the parser state * * A Clp_ParserState object can store a parsing state of a Clp_Parser object. * This state specifies exactly how far the Clp_Parser has gotten in parsing * an argument list. The Clp_SaveParser() and Clp_RestoreParser() functions * can be used to save this state and then restore it later, allowing a * Clp_Parser to switch among argument lists. * * The initial state is empty, in that after Clp_RestoreParser(clp, state), * Clp_Next(clp) would return Clp_Done. * * Parser states can be saved and restored among different parser objects. * * @sa Clp_DeleteParserState, Clp_SaveParser, Clp_RestoreParser */ Clp_ParserState * Clp_NewParserState(void) { Clp_ParserState *state = (Clp_ParserState *)malloc(sizeof(Clp_ParserState)); if (state) { state->argv = 0; state->argc = 0; state->option_chars[0] = 0; state->xtext = 0; state->option_processing = 0; state->opt_generation = 0; state->current_option = -1; state->is_short = 0; state->whole_negated = 0; state->current_short = 0; state->negated_by_no = 0; } return state; } /** @param state parser state * * The memory associated with @a state is freed. */ void Clp_DeleteParserState(Clp_ParserState *state) { free(state); } /** @param clp the parser * @param state parser state * @sa Clp_NewParserState, Clp_RestoreParser */ void Clp_SaveParser(const Clp_Parser *clp, Clp_ParserState *state) { Clp_Internal *cli = clp->internal; state->argv = cli->argv; state->argc = cli->argc; memcpy(state->option_chars, cli->option_chars, Clp_OptionCharsSize); state->xtext = cli->xtext; state->option_processing = cli->option_processing; state->opt_generation = cli->opt_generation; state->current_option = cli->current_option; state->is_short = cli->is_short; state->whole_negated = cli->whole_negated; state->current_short = cli->current_short; state->negated_by_no = cli->negated_by_no; } /** @param clp the parser * @param state parser state * * The parser state in @a state is restored into @a clp. The next call to * Clp_Next() will return the same result as it would have at the time @a * state was saved (probably by Clp_SaveParser(@a clp, @a state)). * * A parser state contains information about arguments (argc and argv; see * Clp_SetArguments()) and option processing (Clp_SetOptionProcessing()), but * not about options (Clp_SetOptions()). Changes to options and value types * are preserved across Clp_RestoreParser(). * * @sa Clp_NewParserState, Clp_SaveParser */ void Clp_RestoreParser(Clp_Parser *clp, const Clp_ParserState *state) { Clp_Internal *cli = clp->internal; cli->argv = state->argv; cli->argc = state->argc; memcpy(cli->option_chars, state->option_chars, Clp_OptionCharsSize); cli->xtext = state->xtext; cli->option_processing = state->option_processing; cli->is_short = state->is_short; cli->whole_negated = state->whole_negated; cli->current_short = state->current_short; cli->negated_by_no = state->negated_by_no; if (cli->opt_generation == state->opt_generation) cli->current_option = state->current_option; else cli->current_option = -1; } /******* * Clp_Next and its helpers **/ static void set_option_text(Clp_Internal *cli, const char *text, int n_option_chars) { assert(n_option_chars < Clp_OptionCharsSize); memcpy(cli->option_chars, text, n_option_chars); cli->option_chars[n_option_chars] = 0; cli->xtext = text + n_option_chars; } static int get_oclass(Clp_Parser *clp, const char *text, int *ocharskip) { int c; if (clp->internal->utf8) { const char *s; c = decode_utf8(text, &s); *ocharskip = s - text; } else { c = (unsigned char) text[0]; *ocharskip = 1; } return Clp_OptionChar(clp, c); } static int next_argument(Clp_Parser *clp, int want_argument) /* Moves clp to the next argument. Returns 1 if it finds another option. Returns 0 if there aren't any more arguments. Returns 0, sets clp->have_val = 1, and sets clp->vstr to the argument if the next argument isn't an option. If want_argument > 0, it'll look for an argument. want_argument == 1: Accept arguments that start with Clp_NotOption or Clp_LongImplicit. want_argument == 2: Accept ALL arguments. Where is the option stored when this returns? Well, cli->argv[0] holds the whole of the next command line argument. cli->option_chars holds a string: what characters began the option? It is generally "-" or "--". cli->text holds the text of the option: for short options, cli->text[0] is the relevant character; for long options, cli->text holds the rest of the option. */ { Clp_Internal *cli = clp->internal; const char *text; int oclass, ocharskip; /* clear relevant flags */ clp->have_val = 0; clp->vstr = 0; cli->could_be_short = 0; /* if we're in a string of short options, move up one char in the string */ if (cli->is_short) { cli->xtext += clp_utf8_charlen(cli, cli->xtext); if (cli->xtext[0] == 0) cli->is_short = 0; else if (want_argument > 0) { /* handle -O[=]argument case */ clp->have_val = 1; if (cli->xtext[0] == '=') clp->vstr = cli->xtext + 1; else clp->vstr = cli->xtext; cli->is_short = 0; return 0; } } /* if in short options, we're all set */ if (cli->is_short) return 1; /** if not in short options, move to the next argument **/ cli->whole_negated = 0; cli->xtext = 0; if (cli->argc <= 1) return 0; cli->argc--; cli->argv++; text = cli->argv[0]; if (want_argument > 1) goto not_option; if (text[0] == '-' && text[1] == '-') { oclass = Clp_DoubledLong; ocharskip = 2; } else oclass = get_oclass(clp, text, &ocharskip); /* If this character could introduce either a short or a long option, try a long option first, but remember that short's a possibility for later. */ if ((oclass & (Clp_Short | Clp_ShortNegated)) && (oclass & (Clp_Long | Clp_LongNegated))) { oclass &= ~(Clp_Short | Clp_ShortNegated); if (text[ocharskip]) cli->could_be_short = 1; } switch (oclass) { case Clp_Short: cli->is_short = 1; goto check_singleton; case Clp_ShortNegated: cli->is_short = 1; cli->whole_negated = 1; goto check_singleton; case Clp_Long: goto check_singleton; case Clp_LongNegated: cli->whole_negated = 1; goto check_singleton; check_singleton: /* For options introduced with one character, option-char, '[option-char]' alone is NOT an option. */ if (!text[ocharskip]) goto not_option; set_option_text(cli, text, ocharskip); break; case Clp_LongImplicit: /* LongImplict: option_chars == "" (since all chars are part of the option); restore head -> text of option */ if (want_argument > 0) goto not_option; set_option_text(cli, text, 0); break; case Clp_DoubledLong: set_option_text(cli, text, ocharskip); break; not_option: case Clp_NotOption: cli->is_short = 0; clp->have_val = 1; clp->vstr = text; return 0; default: assert(0 /* CLP misconfiguration: bad option type */); } return 1; } static void switch_to_short_argument(Clp_Parser *clp) { Clp_Internal *cli = clp->internal; const char *text = cli->argv[0]; int ocharskip, oclass = get_oclass(clp, text, &ocharskip); assert(cli->could_be_short); cli->is_short = 1; cli->whole_negated = (oclass & Clp_ShortNegated ? 1 : 0); set_option_text(cli, cli->argv[0], ocharskip); } static int find_long(Clp_Parser *clp, const char *arg) /* If arg corresponds to one of clp's options, finds that option & returns it. If any argument is given after an = sign in arg, sets clp->have_val = 1 and clp->vstr to that argument. Sets cli->ambiguous to 1 iff there was no match because the argument was ambiguous. */ { Clp_Internal *cli = clp->internal; int optno, len, lmm; const Clp_Option *opt = cli->opt; const Clp_InternOption *iopt; int first_negative_ambiguous; /* Look for a normal option. */ optno = find_prefix_opt (clp, arg, cli->nopt, opt, cli->iopt, &cli->ambiguous, cli->ambiguous_values); if (optno >= 0) goto worked; /* If we can't find it, look for a negated option. */ /* I know this is silly, but it makes me happy to accept --no-no-option as a double negative synonym for --option. :) */ first_negative_ambiguous = cli->ambiguous; while (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-') { arg += 3; clp->negated = !clp->negated; optno = find_prefix_opt (clp, arg, cli->nopt, opt, cli->iopt, &cli->ambiguous, cli->ambiguous_values); if (optno >= 0) goto worked; } /* No valid option was found; return 0. Mark the ambiguous values found through '--no' by making them negative. */ { int i, max = cli->ambiguous; if (max > MAX_AMBIGUOUS_VALUES) max = MAX_AMBIGUOUS_VALUES; for (i = first_negative_ambiguous; i < max; i++) cli->ambiguous_values[i] = -cli->ambiguous_values[i] - 1; } return -1; worked: iopt = &cli->iopt[optno]; lmm = (clp->negated ? iopt->lmmneg : iopt->lmmpos); if (cli->could_be_short && (clp->negated ? iopt->lmmneg_short : iopt->lmmpos_short)) { int first_charlen = clp_utf8_charlen(cli, arg); lmm = (first_charlen >= lmm ? first_charlen + 1 : lmm); } len = argcmp(opt[optno].long_name + iopt->ilongoff, arg, lmm, 1); assert(len > 0); if (arg[len] == '=') { clp->have_val = 1; clp->vstr = arg + len + 1; } return optno; } static int find_short(Clp_Parser *clp, const char *text) /* If short_name corresponds to one of clp's options, returns it. */ { Clp_Internal *cli = clp->internal; const Clp_Option *opt = cli->opt; const Clp_InternOption *iopt = cli->iopt; int i, c; if (clp->internal->utf8) c = decode_utf8(text, 0); else c = (unsigned char) *text; for (i = 0; i < cli->nopt; i++) if (iopt[i].ishort && opt[i].short_name == c && (!clp->negated || iopt[i].ineg)) { clp->negated = clp->negated || !iopt[i].ipos; return i; } return -1; } /** @param clp the parser * @return option ID of next option * * Parse the next argument from the argument list, store information about * that argument in the fields of @a clp, and return the option's ID. * * If an argument was successfully parsed, that option's ID is returned. * Other possible return values are: * *
*
Clp_Done
*
There are no more arguments.
*
Clp_NotOption
*
The next argument was not an option. The argument's text is @a * clp->vstr (and @a clp->val.s).
*
Clp_BadOption
*
The next argument was a bad option: either an option that wasn't * understood, or an option lacking a required value, or an option whose value * couldn't be parsed. The option has been skipped.
*
Clp_Error
*
There was an internal error. This should never occur unless a user * messes with, for example, a Clp_Option array.
*
* * The fields of @a clp are set as follows. * *
*
negated
*
1 if the option was negated, 0 if it wasn't.
*
have_val
*
1 if the option had a value, 0 if it didn't. Note that negated options * are not allowed to have values.
*
vstr
*
The value string, if any. NULL if there was no value.
*
val
*
An option's value type will parse the value string into this * union.
*
* * The parsed argument is shifted off the argument list, so that sequential * calls to Clp_Next() step through the arugment list. */ int Clp_Next(Clp_Parser *clp) { Clp_Internal *cli = clp->internal; int optno; const Clp_Option *opt; Clp_ParserState clpsave; int vtpos, complain; /* Set up clp */ cli->current_option = -1; cli->ambiguous = 0; /* Get the next argument or option */ if (!next_argument(clp, cli->option_processing ? 0 : 2)) { clp->val.s = clp->vstr; optno = clp->have_val ? Clp_NotOption : Clp_Done; clp->option = &clp_option_sentinel[-optno]; return optno; } clp->negated = cli->whole_negated; if (cli->is_short) optno = find_short(clp, cli->xtext); else optno = find_long(clp, cli->xtext); /* If there's ambiguity between long & short options, and we couldn't find a long option, look for a short option */ if (optno < 0 && cli->could_be_short) { switch_to_short_argument(clp); optno = find_short(clp, cli->xtext); } /* If we didn't find an option... */ if (optno < 0 || (clp->negated && !cli->iopt[optno].ineg)) { /* default processing for the "--" option: turn off option processing and return the next argument */ if (strcmp(cli->argv[0], "--") == 0) { Clp_SetOptionProcessing(clp, 0); return Clp_Next(clp); } /* otherwise, report some error or other */ if (cli->ambiguous) ambiguity_error(clp, cli->ambiguous, cli->ambiguous_values, cli->opt, cli->iopt, cli->option_chars, "option %<%s%s%> is ambiguous", cli->option_chars, cli->xtext); else if (cli->is_short && !cli->could_be_short) Clp_OptionError(clp, "unrecognized option %<%s%C%>", cli->option_chars, cli->xtext); else Clp_OptionError(clp, "unrecognized option %<%s%s%>", cli->option_chars, cli->xtext); clp->option = &clp_option_sentinel[-Clp_BadOption]; return Clp_BadOption; } /* Set the current option */ cli->current_option = optno; cli->current_short = cli->is_short; cli->negated_by_no = clp->negated && !cli->whole_negated; /* The no-argument (or should-have-no-argument) case */ if (clp->negated || (!cli->iopt[optno].imandatory && !cli->iopt[optno].ioptional)) { if (clp->have_val) { Clp_OptionError(clp, "%<%O%> can%,t take an argument"); clp->option = &clp_option_sentinel[-Clp_BadOption]; return Clp_BadOption; } else { clp->option = &cli->opt[optno]; return cli->opt[optno].option_id; } } /* Get an argument if we need one, or if it's optional */ /* Sanity-check the argument type. */ opt = &cli->opt[optno]; if (opt->val_type <= 0) { clp->option = &clp_option_sentinel[-Clp_Error]; return Clp_Error; } vtpos = val_type_binsearch(cli, opt->val_type); if (vtpos == cli->nvaltype || cli->valtype[vtpos].val_type != opt->val_type) { clp->option = &clp_option_sentinel[-Clp_Error]; return Clp_Error; } /* complain == 1 only if the argument was explicitly given, or it is mandatory. */ complain = (clp->have_val != 0) || cli->iopt[optno].imandatory; Clp_SaveParser(clp, &clpsave); if (cli->iopt[optno].imandatory && !clp->have_val) { /* Mandatory argument case */ /* Allow arguments to options to start with a dash, but only if the argument type allows it by not setting Clp_DisallowOptions */ int disallow = (cli->valtype[vtpos].flags & Clp_DisallowOptions) != 0; next_argument(clp, disallow ? 1 : 2); if (!clp->have_val) { int got_option = cli->xtext != 0; Clp_RestoreParser(clp, &clpsave); if (got_option) Clp_OptionError(clp, "%<%O%> requires a non-option argument"); else Clp_OptionError(clp, "%<%O%> requires an argument"); clp->option = &clp_option_sentinel[-Clp_BadOption]; return Clp_BadOption; } } else if (cli->is_short && !clp->have_val && cli->xtext[clp_utf8_charlen(cli, cli->xtext)]) /* The -[option]argument case: Assume that the rest of the current string is the argument. */ next_argument(clp, 1); /* Parse the argument */ if (clp->have_val) { Clp_ValType *atr = &cli->valtype[vtpos]; if (atr->func(clp, clp->vstr, complain, atr->user_data) <= 0) { /* parser failed */ clp->have_val = 0; if (cli->iopt[optno].imandatory) { clp->option = &clp_option_sentinel[-Clp_BadOption]; return Clp_BadOption; } else Clp_RestoreParser(clp, &clpsave); } } clp->option = opt; return opt->option_id; } /** @param clp the parser * @param allow_options whether options will be allowed * * Remove and return the next argument from @a clp's argument array. If there * are no arguments left, or if the next argument is an option and @a * allow_options != 0, then returns null. */ const char * Clp_Shift(Clp_Parser *clp, int allow_options) /* Returns the next argument from the argument list without parsing it. If there are no more arguments, returns 0. */ { Clp_ParserState clpsave; Clp_SaveParser(clp, &clpsave); next_argument(clp, allow_options ? 2 : 1); if (!clp->have_val) Clp_RestoreParser(clp, &clpsave); return clp->vstr; } /******* * Clp_OptionError **/ typedef struct Clp_BuildString { char *text; char *pos; int capacity; int bad; } Clp_BuildString; static Clp_BuildString * new_build_string(void) { Clp_BuildString *bs = (Clp_BuildString *)malloc(sizeof(Clp_BuildString)); if (!bs) goto bad; bs->text = (char *)malloc(256); if (!bs->text) goto bad; bs->pos = bs->text; bs->capacity = 256; bs->bad = 0; return bs; bad: if (bs) free(bs); return 0; } static void free_build_string(Clp_BuildString *bs) { if (bs) free(bs->text); free(bs); } static int grow_build_string(Clp_BuildString *bs, int want) { char *new_text; int ipos = bs->pos - bs->text; int new_capacity = bs->capacity; while (want >= new_capacity) new_capacity *= 2; new_text = (char *)realloc(bs->text, new_capacity); if (!new_text) { bs->bad = 1; return 0; } else { bs->text = new_text; bs->pos = bs->text + ipos; bs->capacity = new_capacity; return 1; } } #define ENSURE_BUILD_STRING(bs, space) \ ((((bs)->pos - (bs)->text) + (space) >= (bs)->capacity) \ || grow_build_string((bs), ((bs)->pos - (bs)->text) + (space))) static void append_build_string(Clp_BuildString *bs, const char *s, int l) { if (l < 0) l = strlen(s); if (ENSURE_BUILD_STRING(bs, l)) { memcpy(bs->pos, s, l); bs->pos += l; } } static Clp_BuildString * Clp_VaOptionError(Clp_Parser *clp, Clp_BuildString *bs, const char *fmt, va_list val) { Clp_Internal *cli = clp->internal; const char *percent; int c; if (!bs) bs = new_build_string(); if (!bs) return 0; if (cli->program_name && cli->program_name[0]) { append_build_string(bs, cli->program_name, -1); append_build_string(bs, ": ", 2); } for (percent = strchr(fmt, '%'); percent; percent = strchr(fmt, '%')) { append_build_string(bs, fmt, percent - fmt); switch (*++percent) { case 's': { const char *s = va_arg(val, const char *); if (s) append_build_string(bs, s, -1); else append_build_string(bs, "(null)", 6); break; } case 'C': { const char *s = va_arg(val, const char *); if (cli->utf8) c = decode_utf8(s, 0); else c = (unsigned char) *s; goto char_c; } case 'c': c = va_arg(val, int); goto char_c; char_c: if (ENSURE_BUILD_STRING(bs, 4)) { if (c >= 32 && c <= 126) *bs->pos++ = c; else if (c < 32) { *bs->pos++ = '^'; *bs->pos++ = c + 64; } else if (cli->utf8 && c >= 127 && c < 0x110000) { bs->pos = encode_utf8(bs->pos, 4, c); } else if (c >= 127 && c <= 255) { sprintf(bs->pos, "\\%03o", c & 0xFF); bs->pos += 4; } else { *bs->pos++ = '\\'; *bs->pos++ = '?'; } } break; case 'd': { int d = va_arg(val, int); if (ENSURE_BUILD_STRING(bs, 32)) { sprintf(bs->pos, "%d", d); bs->pos = strchr(bs->pos, 0); } break; } case 'O': { int optno = cli->current_option; const Clp_Option *opt = &cli->opt[optno]; if (optno < 0) append_build_string(bs, "(no current option!)", -1); else if (cli->current_short) { append_build_string(bs, cli->option_chars, -1); if (ENSURE_BUILD_STRING(bs, 5)) { if (cli->utf8) bs->pos = encode_utf8(bs->pos, 5, opt->short_name); else *bs->pos++ = opt->short_name; } } else if (cli->negated_by_no) { append_build_string(bs, cli->option_chars, -1); append_build_string(bs, "no-", 3); append_build_string(bs, opt->long_name + cli->iopt[optno].ilongoff, -1); } else { append_build_string(bs, cli->option_chars, -1); append_build_string(bs, opt->long_name + cli->iopt[optno].ilongoff, -1); } break; } case '%': if (ENSURE_BUILD_STRING(bs, 1)) *bs->pos++ = '%'; break; case '`': /* backwards compatibility */ case '<': append_build_string(bs, (cli->utf8 ? "\342\200\230" : "'"), -1); break; case '\'': /* backwards compatibility */ case ',': case '>': append_build_string(bs, (cli->utf8 ? "\342\200\231" : "'"), -1); break; default: if (ENSURE_BUILD_STRING(bs, 2)) { *bs->pos++ = '%'; *bs->pos++ = *percent; } break; } fmt = ++percent; } append_build_string(bs, fmt, -1); append_build_string(bs, "\n", 1); return bs; } static void do_error(Clp_Parser *clp, Clp_BuildString *bs) { const char *text; if (bs && !bs->bad) { *bs->pos = 0; text = bs->text; } else text = "out of memory\n"; if (clp->internal->error_handler != 0) (*clp->internal->error_handler)(clp, text); else fputs(text, stderr); } /** @param clp the parser * @param format error format * * Format an error message from @a format and any additional arguments in the * ellipsis. The resulting error string by printing it to standard error or * passing it to Clp_SetErrorHandler. * * The following format characters are accepted: * *
*
%c
*
A character (type int). Control characters are printed in * caret notation. If the parser is in UTF-8 mode, the character is formatted * in UTF-8. Otherwise, special characters are printed with backslashes and * octal notation.
*
%s
*
A string (type const char *).
*
%C
*
The argument is a string (type const char *). The first * character in this string is printed. If the parser is in UTF-8 mode, this * may involve multiple bytes.
*
%d
*
An integer (type int). Printed in decimal.
*
%O
*
The current option. No values are read from the argument list; the * current option is defined in the Clp_Parser object itself.
*
%%
*
Prints a percent character.
*
%<
*
Prints an open quote string. In UTF-8 mode, prints a left single * quote. Otherwise prints a single quote.
*
%>
*
Prints a closing quote string. In UTF-8 mode, prints a right single * quote. Otherwise prints a single quote.
*
%,
*
Prints an apostrophe. In UTF-8 mode, prints a right single quote. * Otherwise prints a single quote.
*
* * Note that no flag characters, precision, or field width characters are * currently supported. * * @sa Clp_SetErrorHandler */ int Clp_OptionError(Clp_Parser *clp, const char *format, ...) { Clp_BuildString *bs; va_list val; va_start(val, format); bs = Clp_VaOptionError(clp, 0, format, val); va_end(val); do_error(clp, bs); free_build_string(bs); return 0; } static int ambiguity_error(Clp_Parser *clp, int ambiguous, int *ambiguous_values, const Clp_Option *opt, const Clp_InternOption *iopt, const char *prefix, const char *fmt, ...) { Clp_Internal *cli = clp->internal; Clp_BuildString *bs; int i; va_list val; va_start(val, fmt); bs = Clp_VaOptionError(clp, 0, fmt, val); if (!bs) goto done; if (clp->internal->program_name && clp->internal->program_name[0]) { append_build_string(bs, clp->internal->program_name, -1); append_build_string(bs, ": ", 2); } append_build_string(bs, "(Possibilities are", -1); for (i = 0; i < ambiguous && i < MAX_AMBIGUOUS_VALUES; i++) { int value = ambiguous_values[i]; const char *no_dash = ""; if (value < 0) value = -(value + 1), no_dash = "no-"; if (i == 0) append_build_string(bs, " ", 1); else if (i == ambiguous - 1) append_build_string(bs, (i == 1 ? " and " : ", and "), -1); else append_build_string(bs, ", ", 2); append_build_string(bs, (cli->utf8 ? "\342\200\230" : "'"), -1); append_build_string(bs, prefix, -1); append_build_string(bs, no_dash, -1); append_build_string(bs, opt[value].long_name + iopt[value].ilongoff, -1); append_build_string(bs, (cli->utf8 ? "\342\200\231" : "'"), -1); } if (ambiguous > MAX_AMBIGUOUS_VALUES) append_build_string(bs, ", and others", -1); append_build_string(bs, ".)\n", -1); va_end(val); done: do_error(clp, bs); free_build_string(bs); return 0; } static int copy_string(char *buf, int buflen, int bufpos, const char *what) { int l = strlen(what); if (l > buflen - bufpos - 1) l = buflen - bufpos - 1; memcpy(buf + bufpos, what, l); return l; } /** @param clp the parser * @param buf output buffer * @param len length of output buffer * @return number of characters written to the buffer, not including the terminating NUL * * A string that looks like the last option parsed by @a clp is extracted into * @a buf. The correct option characters are put into the string first, * followed by the option text. The output buffer is null-terminated unless * @a len == 0. * * @sa Clp_CurOptionName */ int Clp_CurOptionNameBuf(Clp_Parser *clp, char *buf, int len) { Clp_Internal *cli = clp->internal; int optno = cli->current_option; int pos = 0; if (optno < 0) pos += copy_string(buf, len, pos, "(no current option!)"); else if (cli->current_short) { pos += copy_string(buf, len, pos, cli->option_chars); if (cli->utf8) pos = (encode_utf8(buf + pos, len - pos - 1, cli->opt[optno].short_name) - buf); else if (pos < len - 1) buf[pos++] = cli->opt[optno].short_name; } else if (cli->negated_by_no) { pos += copy_string(buf, len, pos, cli->option_chars); pos += copy_string(buf, len, pos, "no-"); pos += copy_string(buf, len, pos, cli->opt[optno].long_name + cli->iopt[optno].ilongoff); } else { pos += copy_string(buf, len, pos, cli->option_chars); pos += copy_string(buf, len, pos, cli->opt[optno].long_name + cli->iopt[optno].ilongoff); } if (pos < len) buf[pos] = 0; return pos; } /** @param clp the parser * @return string describing the current option * * This function acts like Clp_CurOptionNameBuf(), but returns a pointer into * a static buffer that will be rewritten on the next call to * Clp_CurOptionName(). * * @note This function is not thread safe. * * @sa Clp_CurOptionName */ const char * Clp_CurOptionName(Clp_Parser *clp) { static char buf[256]; Clp_CurOptionNameBuf(clp, buf, 256); return buf; } #ifdef __cplusplus } #endif lcdf-typetools-2.108/liblcdf/vectorv.cc0000644000175000017500000000453013423375327015026 00000000000000/* * vectorv.cc -- template specialization for Vector * Eddie Kohler * * Copyright (c) 1999-2006 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file. These conditions include: you must * preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */ #ifdef HAVE_CONFIG_H # include #endif #include #include Vector::Vector(const Vector &o) : _l(0), _n(0), _capacity(0) { *this = o; } Vector::~Vector() { delete[] _l; } Vector & Vector::operator=(const Vector &o) { if (&o != this) { _n = 0; if (reserve(o._n)) { _n = o._n; memcpy(_l, o._l, sizeof(void *) * _n); } } return *this; } Vector & Vector::assign(int n, void *e) { _n = 0; resize(n, e); return *this; } bool Vector::reserve(int want) { if (want < 0) want = (_capacity > 0 ? _capacity * 2 : 4); if (want <= _capacity) return true; void **new_l = new void*[want]; if (!new_l) return false; if (_n) { memcpy(new_l, _l, sizeof(void*) * _n); } delete[] _l; _l = new_l; _capacity = want; return true; } Vector::iterator Vector::erase(iterator a, iterator b) { if (b > a) { assert(a >= begin() && b <= end()); memmove(a, b, (end() - b) * sizeof(void*)); _n -= b - a; return a; } else return b; } void Vector::resize(int nn, void *e) { if (nn <= _capacity || reserve(nn)) { for (int i = _n; i < nn; i++) _l[i] = e; _n = nn; } } void Vector::swap(Vector& o) { void **l = _l; int n = _n; int cap = _capacity; _l = o._l; _n = o._n; _capacity = o._capacity; o._l = l; o._n = n; o._capacity = cap; } lcdf-typetools-2.108/liblcdf/fixlibc.c0000664000175000017500000000275012732752520014613 00000000000000/* Provide definitions for missing or incorrect libc functions. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #ifdef __cplusplus extern "C" { #endif #if !HAVE_STRDUP char * strdup(const char *s) { char *t; int l; if (!s) return 0; l = strlen(s) + 1; t = (char *)malloc(l); if (!t) return 0; memcpy(t, s, l); return t; } #endif #if !HAVE_STRERROR /* David Mazieres assures me that this definition works. */ char * strerror(int errno) { extern int sys_nerr; extern char *sys_errlist[]; if (errno < 0 || errno >= sys_nerr) return (char *)"bad error number"; else return sys_errlist[errno]; } #endif #if HAVE_BROKEN_STRTOD /* On NeXTSTEP, Melissa O'Neill reports that strtod consumes whitespace after its argument, which makes mminstance (among other programs) not work. This wrapper gets rid of that whitespace again. (Originally, we suspected strtol too, but it seems to work, at least in NeXTSTEP 3.3 patch 2.) */ double good_strtod(const char *nptr, char **endptr) { double d = strtod(nptr, endptr); if (endptr) while (*endptr > nptr && isspace((unsigned char) (*endptr)[-1])) (*endptr)--; return d; } #endif #if !HAVE_STRNLEN || HAVE_BROKEN_STRNLEN size_t strnlen(const char *s, size_t maxlen) { const char *p = (const char *) memchr(s, 0, maxlen); return p ? p - s : maxlen; } #endif #ifdef __cplusplus } #endif lcdf-typetools-2.108/liblcdf/strtonum.c0000664000175000017500000000116212732752520015062 00000000000000/* -*- related-file-name: "../include/lcdf/strtonum.h" -*- */ #ifdef HAVE_CONFIG_H # include #endif #include #include #if HAVE_BROKEN_STRTOD # define strtod good_strtod #endif #ifdef __cplusplus extern "C" { #endif /* A faster strtod which only calls the real strtod if the string has a fractional part. */ double strtonumber(const char *f, char **endf) { long v = strtol((char *)f, endf, 10); /* handle any possible decimal part */ if (**endf == '.' || **endf == 'E' || **endf == 'e') return strtod((char *)f, endf); else return v; } #ifdef __cplusplus } #endif lcdf-typetools-2.108/liblcdf/landmark.cc0000644000175000017500000000201713423375327015125 00000000000000// -*- related-file-name: "../include/lcdf/landmark.hh" -*- /* landmark.{cc,hh} -- FILE:LINE type landmarks * * Copyright (c) 1998-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include Landmark operator+(const Landmark &landmark, int offset) { if (landmark.has_line()) return Landmark(landmark.file(), landmark.line() + offset); else return landmark; } Landmark::operator String() const { if (_file && has_line()) return _file + ":" + String(_line); else return _file; } lcdf-typetools-2.108/liblcdf/bezier.cc0000644000175000017500000002213313423375327014615 00000000000000// -*- related-file-name: "../include/lcdf/bezier.hh" -*- /* bezier.{cc,hh} -- cubic Bezier curves * * Copyright (c) 1998-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include // // bounding box // void Bezier::make_bb() const noexcept { _bb = 0; for (int i = 1; i < 4; i++) { if (_p[i].x > bb_right_x()) _bb = (_bb & ~0x03) | (i << 0); else if (_p[i].x < bb_left_x()) _bb = (_bb & ~0x0C) | (i << 2); if (_p[i].y > bb_top_x()) _bb = (_bb & ~0x30) | (i << 4); else if (_p[i].y < bb_bottom_x()) _bb = (_bb & ~0xC0) | (i << 6); } } // // is_flat, eval // bool Bezier::is_flat(double t) const noexcept { return (_p[2].on_segment(_p[0], _p[3], t) && _p[1].on_segment(_p[0], _p[3], t)); } static Point eval_bezier(Point *b_in, int degree, double u) { assert(degree < 4); Point b[4]; for (int i = 0; i <= degree; i++) b[i] = b_in[i]; double m = 1.0 - u; for (int i = 1; i <= degree; i++) for (int j = 0; j <= degree - i; j++) b[j] = b[j]*m + b[j+1]*u; return b[0]; } Point Bezier::eval(double u) const noexcept { Bezier b = *this; double m = 1.0 - u; for (int i = 1; i < 4; i++) for (int j = 0; j < 4 - i; j++) b._p[j] = m * b._p[j] + u * b._p[j+1]; return b._p[0]; } // // halve // void Bezier::halve(Bezier &l, Bezier &r) const noexcept { Point half = Point::midpoint(_p[1], _p[2]); l._p[0] = _p[0]; l._p[1] = Point::midpoint(_p[0], _p[1]); l._p[2] = Point::midpoint(l._p[1], half); r._p[3] = _p[3]; r._p[2] = Point::midpoint(_p[2], _p[3]); r._p[1] = Point::midpoint(r._p[2], half); r._p[0] = l._p[3] = Point::midpoint(l._p[2], r._p[1]); } // // hit testing // bool Bezier::in_bb(const Point &p, double tolerance) const noexcept { ensure_bb(); if (bb_right() + tolerance < p.x || bb_left() - tolerance > p.x || bb_top() + tolerance < p.y || bb_bottom() - tolerance > p.y) return false; else return true; } double Bezier::hit_recurse(const Point &p, double tolerance, double leftd, double rightd, double leftt, double rightt) const noexcept { Bezier left, right; double middled, resultt; if (is_flat(tolerance)) { if (p.on_segment(_p[0], _p[3], tolerance)) return (leftt + rightt) / 2; else return -1; } if (leftd < tolerance * tolerance) return leftt; if (rightd < tolerance * tolerance) return rightt; if (!in_bb(p, tolerance)) return -1; halve(left, right); middled = (right._p[0] - p).squared_length(); resultt = left.hit_recurse (p, tolerance, leftd, middled, leftt, (leftt + rightt) / 2); if (resultt >= 0) return resultt; return right.hit_recurse (p, tolerance, middled, rightd, (leftt + rightt) / 2, rightt); } bool Bezier::hit(const Point &p, double tolerance) const noexcept { double leftd = (_p[0] - p).squared_length(); double rightd = (_p[3] - p).squared_length(); double resultt = hit_recurse(p, tolerance, leftd, rightd, 0, 1); return resultt >= 0; } // // segmentize to list of points // // uses recursive subdivision // void Bezier::segmentize(Vector &v, bool first) const { if (is_flat(0.5)) { if (first) v.push_back(_p[0]); v.push_back(_p[3]); } else { Bezier left, right; halve(left, right); left.segmentize(v, first); right.segmentize(v, false); } } // // curve fitting // // code after Philip J. Schneider's algorithm described, with code, in the // first Graphics Gems // static void chord_length_parameterize(const Point *d, int nd, Vector &result) { assert(result.size() == 0); result.reserve(nd); result.push_back(0); for (int i = 1; i < nd; i++) result.push_back(result.back() + Point::distance(d[i-1], d[i])); double last_dist = result.back(); for (int i = 1; i < nd; i++) result[i] /= last_dist; } static inline double B0(double u) { double m = 1.0 - u; return m*m*m; } static inline double B1(double u) { double m = 1.0 - u; return 3*m*m*u; } static inline double B2(double u) { double m = 1.0 - u; return 3*m*u*u; } static inline double B3(double u) { return u*u*u; } static Bezier generate_bezier(const Point *d, int nd, const Vector ¶meters, const Point &left_tangent, const Point &right_tangent) { Point *a0 = new Point[nd]; Point *a1 = new Point[nd]; for (int i = 0; i < nd; i++) { a0[i] = left_tangent * B1(parameters[i]); a1[i] = right_tangent * B2(parameters[i]); } double c[2][2], x[2]; c[0][0] = c[0][1] = c[1][0] = c[1][1] = x[0] = x[1] = 0.0; int last = nd - 1; for (int i = 0; i < nd; i++) { c[0][0] += Point::dot(a0[i], a0[i]); c[0][1] += Point::dot(a0[i], a1[i]); c[1][1] += Point::dot(a1[i], a1[i]); Point tmp = d[i] - (d[0] * (B0(parameters[i]) + B1(parameters[i])) + d[last] * (B2(parameters[i]) + B3(parameters[i]))); x[0] += Point::dot(a0[i], tmp); x[1] += Point::dot(a1[i], tmp); } c[1][0] = c[0][1]; // compute determinants double det_c0_c1 = c[0][0]*c[1][1] - c[1][0]*c[0][1]; double det_c0_x = c[0][0]*x[1] - c[0][1]*x[0]; double det_x_c1 = x[0]*c[1][1] - x[1]*c[0][1]; // finally, derive alpha values if (det_c0_c1 == 0.0) det_c0_c1 = c[0][0]*c[1][1] * 10e-12; double alpha_l = det_x_c1 / det_c0_c1; double alpha_r = det_c0_x / det_c0_c1; // if alpha negative, use the Wu/Barsky heuristic if (alpha_l < 0.0 || alpha_r < 0.0) { double distance = Point::distance(d[0], d[last]) / 3; return Bezier(d[0], d[0] + left_tangent*distance, d[last] + right_tangent*distance, d[last]); } else return Bezier(d[0], d[0] + left_tangent*alpha_l, d[last] + right_tangent*alpha_r, d[last]); } static double newton_raphson_root_find(const Bezier &b, const Point &p, double u) { const Point *b_pts = b.points(); Point b_det[3]; for (int i = 0; i < 3; i++) b_det[i] = (b_pts[i+1] - b_pts[i]) * 3; Point b_det_det[2]; for (int i = 0; i < 2; i++) b_det_det[i] = (b_det[i+1] - b_det[i]) * 2; Point b_u = b.eval(u); Point b_det_u = eval_bezier(b_det, 2, u); Point b_det_det_u = eval_bezier(b_det_det, 1, u); double numerator = Point::dot(b_u - p, b_det_u); double denominator = Point::dot(b_det_u, b_det_u) + Point::dot(b_u - p, b_det_det_u); return u - numerator/denominator; } static void reparameterize(const Point *d, int nd, Vector ¶meters, const Bezier &b) { for (int i = 0; i < nd; i++) parameters[i] = newton_raphson_root_find(b, d[i], parameters[i]); } static double compute_max_error(const Point *d, int nd, const Bezier &b, const Vector ¶meters, int *split_point) { *split_point = nd/2; double max_dist = 0.0; for (int i = 1; i < nd - 1; i++) { double dist = (b.eval(parameters[i]) - d[i]).squared_length(); if (dist >= max_dist) { max_dist = dist; *split_point = i; } } return max_dist; } static void fit0(const Point *d, int nd, Point left_tangent, Point right_tangent, double error, Vector &result) { // Use a heuristic for small regions (only two points) if (nd == 2) { double dist = Point::distance(d[0], d[1]) / 3; result.push_back(Bezier(d[0], d[0] + dist*left_tangent, d[1] + dist*right_tangent, d[1])); return; } // Parameterize points and attempt to fit curve Vector parameters; chord_length_parameterize(d, nd, parameters); Bezier b = generate_bezier(d, nd, parameters, left_tangent, right_tangent); // find max error int split_point; double max_error = compute_max_error(d, nd, b, parameters, &split_point); if (max_error < error) { result.push_back(b); return; } // if error not too large, try iteration and reparameterization if (max_error < error*error) for (int i = 0; i < 4; i++) { reparameterize(d, nd, parameters, b); b = generate_bezier(d, nd, parameters, left_tangent, right_tangent); max_error = compute_max_error(d, nd, b, parameters, &split_point); if (max_error < error) { result.push_back(b); return; } } // fitting failed -- split at max error point and fit again Point center_tangent = ((d[split_point-1] - d[split_point+1])/2).normal(); fit0(d, split_point+1, left_tangent, center_tangent, error, result); fit0(d+split_point, nd-split_point, -center_tangent, right_tangent, error, result); } void Bezier::fit(const Vector &points, double error, Vector &result) { int npoints = points.size(); Point left_tangent = (points[1] - points[0]).normal(); Point right_tangent = (points[npoints-2] - points[npoints-1]).normal(); fit0(&points[0], npoints, left_tangent, right_tangent, error, result); } lcdf-typetools-2.108/liblcdf/transform.cc0000644000175000017500000000721313423375327015352 00000000000000// -*- related-file-name: "../include/lcdf/transform.hh" -*- /* transform.{cc,hh} -- planar affine transformations * * Copyright (c) 2000-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include Transform::Transform() { _m[0] = _m[3] = 1; _m[1] = _m[2] = _m[4] = _m[5] = 0; _null = true; } Transform::Transform(const double m[6]) { _m[0] = m[0]; _m[1] = m[1]; _m[2] = m[2]; _m[3] = m[3]; _m[4] = m[4]; _m[5] = m[5]; check_null(0); } Transform::Transform(double m0, double m1, double m2, double m3, double m4, double m5) { _m[0] = m0; _m[1] = m1; _m[2] = m2; _m[3] = m3; _m[4] = m4; _m[5] = m5; check_null(0); } void Transform::check_null(double tolerance) { _null = (fabs(_m[0] - 1) < tolerance && fabs(_m[1]) < tolerance && fabs(_m[2]) < tolerance && fabs(_m[3] - 1) < tolerance && fabs(_m[4]) < tolerance && fabs(_m[5]) < tolerance); } void Transform::scale(double x, double y) { _m[0] *= x; _m[1] *= x; _m[2] *= y; _m[3] *= y; if (x != 1 || y != 1) _null = false; } void Transform::rotate(double r) { double c = cos(r); double s = sin(r); double a = _m[0], b = _m[2]; _m[0] = a*c + b*s; _m[2] = b*c - a*s; a = _m[1], b = _m[3]; _m[1] = a*c + b*s; _m[3] = b*c - a*s; if (r != 0) _null = false; } void Transform::translate(double x, double y) { _m[4] += _m[0]*x + _m[2]*y; _m[5] += _m[1]*x + _m[3]*y; if (x != 0 || y != 0) _null = false; } void Transform::raw_translate(double x, double y) { _m[4] += x; _m[5] += y; if (x != 0 || y != 0) _null = false; } void Transform::shear(double s) { *this *= Transform(1, 0, s, 1, 0, 0); } Transform& Transform::operator*=(const Transform& x) { if (x.null()) /* do nothing */; else if (null()) memcpy(_m, x._m, sizeof(_m)); else { double m[6]; m[0] = _m[0] * x._m[0] + _m[2] * x._m[1]; m[1] = _m[1] * x._m[0] + _m[3] * x._m[1]; m[2] = _m[0] * x._m[2] + _m[2] * x._m[3]; m[3] = _m[1] * x._m[2] + _m[3] * x._m[3]; m[4] = _m[0] * x._m[4] + _m[2] * x._m[5] + _m[4]; m[5] = _m[1] * x._m[4] + _m[3] * x._m[5] + _m[5]; memcpy(_m, m, sizeof(_m)); } return *this; } void Transform::real_apply_to(Point &p) const { double x = p.x; p.x = x*_m[0] + p.y*_m[2] + _m[4]; p.y = x*_m[1] + p.y*_m[3] + _m[5]; } Point Transform::real_apply(const Point &p) const { return Point(p.x*_m[0] + p.y*_m[2] + _m[4], p.x*_m[1] + p.y*_m[3] + _m[5]); } Bezier & operator*=(Bezier &b, const Transform &t) { if (!t.null()) { b.mpoint(0) *= t; b.mpoint(1) *= t; b.mpoint(2) *= t; b.mpoint(3) *= t; } return b; } Bezier operator*(const Bezier &b, const Transform &t) { return (t.null() ? b : Bezier(b.point(0) * t, b.point(1) * t, b.point(2) * t, b.point(3) * t)); } String Transform::unparse() const { StringAccum sa; sa << '['; for (int i = 0; i < 6; i++) { if (i) sa << ',' << ' '; sa << _m[i]; } sa << ']'; return sa.take_string(); } lcdf-typetools-2.108/liblcdf/permstr.cc0000644000175000017500000002151413423375327015033 00000000000000// -*- related-file-name: "../include/lcdf/permstr.hh" -*- /* permstr.{cc,hh} -- permanent strings * * Copyright (c) 1998-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include static PermString::Initializer initializer; PermString::Doodad PermString::zero_char_doodad = { 0, 0, { 0, 0 } }; PermString::Doodad PermString::one_char_doodad[256]; PermString::Doodad* PermString::buckets[NHASH]; PermString::Initializer::Initializer() { static int initialized = 0; if (!initialized) { PermString::static_initialize(); initialized = 1; } } void PermString::static_initialize() { for (int i = 0; i < 256; i++) { one_char_doodad[i].next = 0; one_char_doodad[i].length = 1; one_char_doodad[i].data[0] = i; one_char_doodad[i].data[1] = 0; } } // This scatter array, and the ideas behind it, are stolen from lcc. static int scatter[] = { /* map characters to random values */ 2078917053, 143302914, 1027100827, 1953210302, 755253631, 2002600785, 1405390230, 45248011, 1099951567, 433832350, 2018585307, 438263339, 813528929, 1703199216, 618906479, 573714703, 766270699, 275680090, 1510320440, 1583583926, 1723401032, 1965443329, 1098183682, 1636505764, 980071615, 1011597961, 643279273, 1315461275, 157584038, 1069844923, 471560540, 89017443, 1213147837, 1498661368, 2042227746, 1968401469, 1353778505, 1300134328, 2013649480, 306246424, 1733966678, 1884751139, 744509763, 400011959, 1440466707, 1363416242, 973726663, 59253759, 1639096332, 336563455, 1642837685, 1215013716, 154523136, 593537720, 704035832, 1134594751, 1605135681, 1347315106, 302572379, 1762719719, 269676381, 774132919, 1851737163, 1482824219, 125310639, 1746481261, 1303742040, 1479089144, 899131941, 1169907872, 1785335569, 485614972, 907175364, 382361684, 885626931, 200158423, 1745777927, 1859353594, 259412182, 1237390611, 48433401, 1902249868, 304920680, 202956538, 348303940, 1008956512, 1337551289, 1953439621, 208787970, 1640123668, 1568675693, 478464352, 266772940, 1272929208, 1961288571, 392083579, 871926821, 1117546963, 1871172724, 1771058762, 139971187, 1509024645, 109190086, 1047146551, 1891386329, 994817018, 1247304975, 1489680608, 706686964, 1506717157, 579587572, 755120366, 1261483377, 884508252, 958076904, 1609787317, 1893464764, 148144545, 1415743291, 2102252735, 1788268214, 836935336, 433233439, 2055041154, 2109864544, 247038362, 299641085, 834307717, 1364585325, 23330161, 457882831, 1504556512, 1532354806, 567072918, 404219416, 1276257488, 1561889936, 1651524391, 618454448, 121093252, 1010757900, 1198042020, 876213618, 124757630, 2082550272, 1834290522, 1734544947, 1828531389, 1982435068, 1002804590, 1783300476, 1623219634, 1839739926, 69050267, 1530777140, 1802120822, 316088629, 1830418225, 488944891, 1680673954, 1853748387, 946827723, 1037746818, 1238619545, 1513900641, 1441966234, 367393385, 928306929, 946006977, 985847834, 1049400181, 1956764878, 36406206, 1925613800, 2081522508, 2118956479, 1612420674, 1668583807, 1800004220, 1447372094, 523904750, 1435821048, 923108080, 216161028, 1504871315, 306401572, 2018281851, 1820959944, 2136819798, 359743094, 1354150250, 1843084537, 1306570817, 244413420, 934220434, 672987810, 1686379655, 1301613820, 1601294739, 484902984, 139978006, 503211273, 294184214, 176384212, 281341425, 228223074, 147857043, 1893762099, 1896806882, 1947861263, 1193650546, 273227984, 1236198663, 2116758626, 489389012, 593586330, 275676551, 360187215, 267062626, 265012701, 719930310, 1621212876, 2108097238, 2026501127, 1865626297, 894834024, 552005290, 1404522304, 48964196, 5816381, 1889425288, 188942202, 509027654, 36125855, 365326415, 790369079, 264348929, 513183458, 536647531, 13672163, 313561074, 1730298077, 286900147, 1549759737, 1699573055, 776289160, 2143346068, 1975249606, 1136476375, 262925046, 92778659, 1856406685, 1884137923, 53392249, 1735424165, 1602280572 }; void PermString::initialize(const char* s, int length) { const unsigned char* m = reinterpret_cast(s); const unsigned char* mm; if (length < 0) length = (s ? strlen(s) : 0); if (length == 0) { _rep = zero_char_doodad.data; return; } else if (length == 1) { _rep = one_char_doodad[m[0]].data; return; } unsigned hash; int l; for (hash = 0, l = length, mm = m; l; mm++, l--) hash = (hash << 1) + scatter[*mm]; hash &= (NHASH - 1); Doodad *buck; for (buck = buckets[hash]; buck; buck = buck->next) if (length == buck->length && memcmp(s, buck->data, length) == 0) { _rep = buck->data; return; } // CANNOT USE new because the structure has variable size. buck = (Doodad *)malloc(sizeof(Doodad) + length - 1); buck->next = buckets[hash]; buckets[hash] = buck; buck->length = length; memcpy(buck->data, s, length); buck->data[length] = 0; _rep = buck->data; } static int pspos; static int pscap = 64; static char *psc = (char *)malloc(pscap); static void append(const char *s, int len) { if (pspos + len >= pscap) { pscap *= 2; psc = (char *)realloc(psc, pscap); } memcpy(psc + pspos, s, len); pspos += len; } inline static void extend(int len) { while (pspos + len >= pscap) { pscap *= 2; psc = (char *)realloc(psc, pscap); } } PermString vpermprintf(const char *s, va_list val) { pspos = 0; while (1) { const char *pct = strchr(s, '%'); if (!pct) { if (*s) append(s, strlen(s)); break; } if (pct != s) { append(s, pct - s); s = pct; } int iflag = -1; while (1) switch (*++s) { case '0': /* zeroflag = 1; */ break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': assert(iflag == -1 /* Too many decimal flags in permprintf */); iflag = 0; while (*s >= '0' && *s <= '9') { iflag = iflag * 10 + *s - '0'; s++; } break; case '*': assert(iflag == -1 /* iflag given */); iflag = va_arg(val, int); break; case 's': { const char *x = va_arg(val, const char *); if (x) { if (iflag < 0) append(x, strlen(x)); else append(x, iflag); } goto pctdone; } case 'c': { char c = (char)(va_arg(val, int) & 0xFF); append(&c, 1); goto pctdone; } case 'p': { PermString::Capsule x = va_arg(val, PermString::Capsule); PermString px; if (x) px = PermString::decapsule(x); if (iflag < 0 || iflag > px.length()) append(px.c_str(), px.length()); else append(px.c_str(), iflag); goto pctdone; } case 'd': { // FIXME FIXME rewrite for sense int x = va_arg(val, int); if (pspos == pscap) extend(1); // FIXME -2^31 unsigned int ux = x; if (x < 0) { psc[pspos++] = '-'; ux = -x; } int numdigits = 0; for (unsigned digcountx = ux; digcountx > 9; digcountx /= 10) numdigits++; extend(numdigits + 1); int digit = numdigits; do { psc[pspos + digit] = (ux % 10) + '0'; ux /= 10; digit--; } while (ux); pspos += numdigits + 1; goto pctdone; } case 'g': { // FIXME FIXME rewrite for sense double x = va_arg(val, double); char buffer[1000]; int len; sprintf(buffer, "%.10g%n", x, &len); extend(len); strcpy(psc + pspos, buffer); pspos += len; goto pctdone; } default: assert(0 /* Bad % in permprintf */); goto pctdone; } pctdone: s++; } return PermString(psc, pspos); } PermString permprintf(const char *s, ...) { va_list val; va_start(val, s); PermString p = vpermprintf(s, val); va_end(val); return p; } PermString permcat(PermString a, PermString b) { if (!a || !b) return a ? a : b; unsigned al = a.length(); unsigned bl = b.length(); char *s = new char[al + bl]; memcpy(s, a.c_str(), al); memcpy(s + al, b.c_str(), bl); PermString p(s, al + bl); delete[] s; return p; } lcdf-typetools-2.108/liblcdf/straccum.cc0000644000175000017500000001771113423375327015164 00000000000000// -*- related-file-name: "../include/lcdf/straccum.hh" -*- /* * straccum.{cc,hh} -- build up strings with operator<< * Eddie Kohler * * Copyright (c) 1999-2000 Massachusetts Institute of Technology * Copyright (c) 2001-2019 Eddie Kohler * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file. These conditions include: you must * preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include /** @class StringAccum * @brief Efficiently build up Strings from pieces. * * Like the String class, StringAccum represents a string of characters. * However, unlike a String, a StringAccum is inherently mutable, and * efficiently supports building up a large string from many smaller pieces. * * StringAccum objects support operator<<() operations for most fundamental * data types. A StringAccum is generally built up by operator<<(), and then * turned into a String by the take_string() method. Extracting the String * from a StringAccum does no memory allocation or copying; the StringAccum's * memory is donated to the String. * *

Out-of-memory StringAccums

* * When there is not enough memory to add requested characters to a * StringAccum object, the object becomes a special "out-of-memory" * StringAccum. Out-of-memory objects are contagious: the result of any * concatenation operation involving an out-of-memory StringAccum is another * out-of-memory StringAccum. Appending an out-of-memory String with "sa << * s" makes "sa" out-of-memory. (However, other usually-equivalent calls, * such as "sa.append(s.begin(), s.end())", do not make "sa" * out-of-memory.) Calling take_string() on an out-of-memory StringAccum * returns an out-of-memory String. * * Out-of-memory StringAccum objects have length zero. */ void StringAccum::assign_out_of_memory() { assert(_cap >= 0); if (_cap > 0) delete[] (_s - MEMO_SPACE); _s = reinterpret_cast(const_cast(String::out_of_memory_data())); _cap = -1; _len = 0; } char * StringAccum::grow(int want) { // can't append to out-of-memory strings if (_cap < 0) { errno = ENOMEM; return 0; } int ncap = (_cap ? (_cap + MEMO_SPACE) * 2 : 128) - MEMO_SPACE; while (ncap <= want) ncap = (ncap + MEMO_SPACE) * 2 - MEMO_SPACE; unsigned char *n = new unsigned char[ncap + MEMO_SPACE]; if (!n) { assign_out_of_memory(); errno = ENOMEM; return 0; } n += MEMO_SPACE; if (_s) { memcpy(n, _s, _len); delete[] (_s - MEMO_SPACE); } _s = n; _cap = ncap; return reinterpret_cast(_s + _len); } int StringAccum::resize(int len) { assert(len >= 0); if (len > _cap && !grow(len)) return -ENOMEM; else { _len = len; return 0; } } char * StringAccum::hard_extend(int nadjust, int nreserve) { char *x = grow(_len + nadjust + nreserve); if (x) _len += nadjust; return x; } const char * StringAccum::c_str() { if (_len < _cap || grow(_len)) _s[_len] = '\0'; return reinterpret_cast(_s); } void StringAccum::append_fill(int c, int len) { if (char *s = extend(len)) memset(s, c, len); } void StringAccum::append_utf8_hard(unsigned ch) { if (ch < 0x80) append((unsigned char) ch); else if (ch < 0x800) { append((unsigned char) (0xC0 + ((ch >> 6) & 0x1F))); append((unsigned char) (0x80 + (ch & 0x3F))); } else if (ch < 0x10000) { append((unsigned char) (0xE0 + ((ch >> 12) & 0x0F))); append((unsigned char) (0x80 + ((ch >> 6) & 0x3F))); append((unsigned char) (0x80 + (ch & 0x3F))); } else if (ch < 0x110000) { append((unsigned char) (0xF0 + ((ch >> 18) & 0x07))); append((unsigned char) (0x80 + ((ch >> 12) & 0x3F))); append((unsigned char) (0x80 + ((ch >> 6) & 0x3F))); append((unsigned char) (0x80 + (ch & 0x3F))); } else append((unsigned char) '?'); } void StringAccum::hard_append(const char *s, int len) { // We must be careful about calls like "sa.append(sa.begin(), sa.end())"; // a naive implementation might use sa's data after freeing it. const char *my_s = reinterpret_cast(_s); if (len <= 0) { // do nothing } else if (_len + len <= _cap) { success: memcpy(_s + _len, s, len); _len += len; } else if (s < my_s || s >= my_s + _cap) { if (grow(_len + len)) goto success; } else { unsigned char *old_s = _s; int old_len = _len; _s = 0; _len = 0; _cap = 0; if (char *new_s = extend(old_len + len)) { memcpy(new_s, old_s, old_len); memcpy(new_s + old_len, s, len); } delete[] (old_s - MEMO_SPACE); } } void StringAccum::append(const char *s) { hard_append(s, strlen(s)); } String StringAccum::take_string() { int len = length(); int cap = _cap; char *str = reinterpret_cast(_s); if (len > 0) { _s = 0; _len = _cap = 0; return String::make_claim(str, len, cap); } else if (!out_of_memory()) return String(); else { clear(); return String::make_out_of_memory(); } } void StringAccum::swap(StringAccum &o) { unsigned char *os = o._s; int olen = o._len, ocap = o._cap; o._s = _s; o._len = _len, o._cap = _cap; _s = os; _len = olen, _cap = ocap; } /** @relates StringAccum @brief Append decimal representation of @a i to @a sa. @return @a sa */ StringAccum & operator<<(StringAccum &sa, long i) { if (char *x = sa.reserve(24)) { int len = sprintf(x, "%ld", i); sa.adjust_length(len); } return sa; } /** @relates StringAccum @brief Append decimal representation of @a u to @a sa. @return @a sa */ StringAccum & operator<<(StringAccum &sa, unsigned long u) { if (char *x = sa.reserve(24)) { int len = sprintf(x, "%lu", u); sa.adjust_length(len); } return sa; } StringAccum & operator<<(StringAccum &sa, double d) { if (char *x = sa.reserve(256)) { int len = sprintf(x, "%.12g", d); sa.adjust_length(len); } return sa; } StringAccum & StringAccum::snprintf(int n, const char *format, ...) { va_list val; va_start(val, format); if (char *x = reserve(n + 1)) { #if HAVE_VSNPRINTF int len = vsnprintf(x, n + 1, format, val); #else int len = vsprintf(x, format, val); assert(len <= n); #endif adjust_length(len); } va_end(val); return *this; } void StringAccum::append_break_lines(const String& text, int linelen, const String &leftmargin) { if (text.length() == 0) return; const char* line = text.begin(); const char* ends = text.end(); linelen -= leftmargin.length(); for (const char* s = line; s < ends; s++) { const char* start = s; while (s < ends && isspace((unsigned char) *s)) s++; const char* word = s; while (s < ends && !isspace((unsigned char) *s)) s++; if (s - line > linelen && start > line) { *this << leftmargin; append(line, start - line); *this << '\n'; line = word; } } if (line < text.end()) { *this << leftmargin; append(line, text.end() - line); *this << '\n'; } } lcdf-typetools-2.108/liblcdf/Makefile.in0000644000175000017500000004607113423376574015107 00000000000000# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : @FIXLIBC_TRUE@am__append_1 = fixlibc.c subdir = liblcdf ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/lcdf-typetools.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/autoconf.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru AM_V_AR = $(am__v_AR_@AM_V@) am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) am__v_AR_0 = @echo " AR " $@; am__v_AR_1 = liblcdf_a_AR = $(AR) $(ARFLAGS) liblcdf_a_DEPENDENCIES = am__liblcdf_a_SOURCES_DIST = bezier.cc clp.c error.cc filename.cc \ globmatch.cc landmark.cc md5.c permstr.cc point.cc slurper.cc \ straccum.cc string.cc strtonum.c transform.cc vectorv.cc \ fixlibc.c @FIXLIBC_TRUE@am__objects_1 = fixlibc.$(OBJEXT) am_liblcdf_a_OBJECTS = bezier.$(OBJEXT) clp.$(OBJEXT) error.$(OBJEXT) \ filename.$(OBJEXT) globmatch.$(OBJEXT) landmark.$(OBJEXT) \ md5.$(OBJEXT) permstr.$(OBJEXT) point.$(OBJEXT) \ slurper.$(OBJEXT) straccum.$(OBJEXT) string.$(OBJEXT) \ strtonum.$(OBJEXT) transform.$(OBJEXT) vectorv.$(OBJEXT) \ $(am__objects_1) liblcdf_a_OBJECTS = $(am_liblcdf_a_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(liblcdf_a_SOURCES) DIST_SOURCES = $(am__liblcdf_a_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KPATHSEA_DEPEND = @KPATHSEA_DEPEND@ KPATHSEA_INCLUDES = @KPATHSEA_INCLUDES@ KPATHSEA_LIBS = @KPATHSEA_LIBS@ KPATHSEA_RULE = @KPATHSEA_RULE@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SELECTED_SUBDIRS = @SELECTED_SUBDIRS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TEMPLATE_OBJS = @TEMPLATE_OBJS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ encdir = @encdir@ exec_prefix = @exec_prefix@ glyphlistdir = @glyphlistdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign noinst_LIBRARIES = liblcdf.a liblcdf_a_SOURCES = bezier.cc clp.c error.cc filename.cc globmatch.cc \ landmark.cc md5.c permstr.cc point.cc slurper.cc straccum.cc \ string.cc strtonum.c transform.cc vectorv.cc $(am__append_1) liblcdf_a_LIBADD = @TEMPLATE_OBJS@ CLEANFILES = @TEMPLATE_OBJS@ AM_CPPFLAGS = -I$(srcdir)/../include EXTRA_DIST = fixlibc.c all: all-am .SUFFIXES: .SUFFIXES: .c .cc .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign liblcdf/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign liblcdf/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) liblcdf.a: $(liblcdf_a_OBJECTS) $(liblcdf_a_DEPENDENCIES) $(EXTRA_liblcdf_a_DEPENDENCIES) $(AM_V_at)-rm -f liblcdf.a $(AM_V_AR)$(liblcdf_a_AR) liblcdf.a $(liblcdf_a_OBJECTS) $(liblcdf_a_LIBADD) $(AM_V_at)$(RANLIB) liblcdf.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bezier.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filename.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fixlibc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/globmatch.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/landmark.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/permstr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/point.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slurper.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/straccum.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strtonum.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transform.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vectorv.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lcdf-typetools-2.108/liblcdf/filename.cc0000644000175000017500000000533413423375327015121 00000000000000// -*- related-file-name: "../include/lcdf/filename.hh" -*- /* filename.{cc,hh} -- filenames * * Copyright (c) 1999-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #ifndef PATHNAME_SEPARATOR # define PATHNAME_SEPARATOR '/' #endif #ifndef CURRENT_DIRECTORY # define CURRENT_DIRECTORY "./" #endif Filename::Filename(const String &fn) : _path(fn), _actual(0) { if (!fn) return; int last_slash = fn.find_right(PATHNAME_SEPARATOR); if (last_slash >= 0) { _dir = _path.substring(0, last_slash + 1); _name = _path.substring(last_slash + 1); } else { _dir = CURRENT_DIRECTORY; _name = fn; } assert(_dir.back() == PATHNAME_SEPARATOR); } Filename::Filename(const String &dir, const String &name) : _name(name), _actual(0) { if (!name) return; if (_name[0] == PATHNAME_SEPARATOR) _dir = ""; else if (dir) { _dir = dir; if (dir.back() != PATHNAME_SEPARATOR) _dir += PATHNAME_SEPARATOR; } else _dir = CURRENT_DIRECTORY; int slash = name.find_right(PATHNAME_SEPARATOR); if (slash >= 0) { _dir += name.substring(0, slash + 1); _name = name.substring(slash + 1); } _path = _dir + _name; } Filename::Filename(FILE *actual, const String &name) : _name(name), _path(name), _actual(actual) { } String Filename::extension() const { int dot = _name.find_right('.'); while (dot > 0 && _name[dot - 1] == '.') dot--; if (dot > 0) return _name.substring(dot + 1); else return String(); } String Filename::base() const { if (String ex = extension()) return _name.substring(0, _name.length() - ex.length() - 1); else return _name; } FILE * Filename::open_read(bool binary) const { if (_actual || !_path) return _actual; else return fopen(_path.c_str(), binary ? "rb" : "r"); } bool Filename::readable() const { struct stat s; if (!_path) return false; return _actual || (_path && (stat(_path.c_str(), &s) >= 0)); } FILE * Filename::open_write(bool binary) const { if (_actual || !_path) return _actual; else return fopen(_path.c_str(), binary ? "wb" : "w"); } lcdf-typetools-2.108/liblcdf/string.cc0000644000175000017500000005013213423375327014643 00000000000000// -*- related-file-name: "../include/lcdf/string.hh" -*- /* * string.{cc,hh} -- a String class with shared substrings * Eddie Kohler * * Copyright (c) 1999-2000 Massachusetts Institute of Technology * Copyright (c) 2001-2019 Eddie Kohler * Copyright (c) 2008-2009 Meraki, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file. These conditions include: you must * preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #ifndef likely #define likely(x) (x) #endif #ifndef unlikely #define unlikely(x) (x) #endif /** @file string.hh * @brief The LCDF String class. */ /** @class String * @brief A string of characters. * * The String class represents a string of characters. Strings may be * constructed from C strings, characters, numbers, and so forth. They may * also be added together. The underlying character arrays are dynamically * allocated; String operations allocate and free memory as needed. A String * and its substrings generally share memory. Accessing a character by index * takes O(1) time; so does creating a substring. * *

Out-of-memory strings

* * When there is not enough memory to create a particular string, a special * "out-of-memory" string is returned instead. Out-of-memory strings are * contagious: the result of any concatenation operation involving an * out-of-memory string is another out-of-memory string. Thus, the final * result of a series of String operations will be an out-of-memory string, * even if the out-of-memory condition occurs in the middle. * * Out-of-memory strings have zero characters, but they aren't equal to other * empty strings. If @a s is a normal String (even an empty string), and @a * oom is an out-of-memory string, then @a s @< @a oom. * * All out-of-memory strings are equal and share the same data(), which is * different from the data() of any other string. See * String::out_of_memory_data(). The String::make_out_of_memory() function * returns an out-of-memory string. */ const char String::null_data = '\0'; const char String::oom_data = '\0'; const char String::bool_data[] = "true\0false"; const char String::int_data[] = "0\0001\0002\0003\0004\0005\0006\0007\0008\0009"; #if HAVE_STRING_PROFILING > 1 # define MEMO_INITIALIZER_TAIL , 0, 0 #else # define MEMO_INITIALIZER_TAIL #endif const String::rep_t String::null_string_rep = { &null_data, 0, 0 }; const String::rep_t String::oom_string_rep = { &oom_data, 0, 0 }; #if HAVE_STRING_PROFILING uint64_t String::live_memo_count; uint64_t String::memo_sizes[55]; uint64_t String::live_memo_sizes[55]; uint64_t String::live_memo_bytes[55]; # if HAVE_STRING_PROFILING > 1 String::memo_t *String::live_memos[55]; # endif #endif /** @cond never */ String::memo_t * String::create_memo(char *space, int dirty, int capacity) { assert(capacity > 0 && capacity >= dirty); memo_t *memo; if (space) memo = reinterpret_cast(space); else memo = reinterpret_cast(new char[MEMO_SPACE + capacity]); if (memo) { memo->capacity = capacity; memo->dirty = dirty; memo->refcount = (space ? 0 : 1); #if HAVE_STRING_PROFILING int bucket = profile_memo_size_bucket(dirty, capacity); ++memo_sizes[bucket]; ++live_memo_sizes[bucket]; live_memo_bytes[bucket] += capacity; ++live_memo_count; # if HAVE_STRING_PROFILING > 1 memo->pprev = &live_memos[bucket]; if ((memo->next = *memo->pprev)) memo->next->pprev = &memo->next; *memo->pprev = memo; # endif #endif } return memo; } void String::delete_memo(memo_t *memo) { assert(memo->capacity > 0); assert(memo->capacity >= memo->dirty); #if HAVE_STRING_PROFILING int bucket = profile_memo_size_bucket(memo->dirty, memo->capacity); --live_memo_sizes[bucket]; live_memo_bytes[bucket] -= memo->capacity; --live_memo_count; # if HAVE_STRING_PROFILING > 1 if ((*memo->pprev = memo->next)) memo->next->pprev = memo->pprev; # endif #endif delete[] reinterpret_cast(memo); } #if HAVE_STRING_PROFILING void String::one_profile_report(StringAccum &sa, int i, int examples) { if (i <= 16) sa << "memo_dirty_" << i; else if (i < 25) { uint32_t s = (i - 17) * 2 + 17; sa << "memo_cap_" << s << '_' << (s + 1); } else if (i < 29) { uint32_t s = (i - 25) * 8 + 33; sa << "memo_cap_" << s << '_' << (s + 7); } else { uint32_t s1 = (1U << (i - 23)) + 1; uint32_t s2 = (s1 - 1) << 1; sa << "memo_cap_" << s1 << '_' << s2; } sa << '\t' << live_memo_sizes[i] << '\t' << memo_sizes[i] << '\t' << live_memo_bytes[i] << '\n'; if (examples) { # if HAVE_STRING_PROFILING > 1 for (memo_t *m = live_memos[i]; m; m = m->next) { sa << " [" << m->dirty << "] "; uint32_t dirty = m->dirty; if (dirty > 0 && m->real_data[dirty - 1] == '\0') --dirty; sa.append(m->real_data, dirty > 128 ? 128 : dirty); sa << '\n'; } # endif } } void String::profile_report(StringAccum &sa, int examples) { uint64_t all_live_sizes = 0, all_sizes = 0, all_live_bytes = 0; for (int i = 0; i < 55; ++i) { if (memo_sizes[i]) one_profile_report(sa, i, examples); all_live_sizes += live_memo_sizes[i]; all_sizes += memo_sizes[i]; all_live_bytes += live_memo_bytes[i]; } sa << "memo_total\t" << all_live_sizes << '\t' << all_sizes << '\t' << all_live_bytes << '\n'; } #endif /** @endcond never */ /** @brief Construct a base-10 string representation of @a x. */ String::String(int x) { if (x >= 0 && x < 10) assign_memo(int_data + 2 * x, 1, 0); else { char buf[128]; sprintf(buf, "%d", x); assign(buf, -1, false); } } /** @overload */ String::String(unsigned x) { if (x < 10) assign_memo(int_data + 2 * x, 1, 0); else { char buf[128]; sprintf(buf, "%u", x); assign(buf, -1, false); } } /** @overload */ String::String(long x) { if (x >= 0 && x < 10) assign_memo(int_data + 2 * x, 1, 0); else { char buf[128]; sprintf(buf, "%ld", x); assign(buf, -1, false); } } /** @overload */ String::String(unsigned long x) { if (x < 10) assign_memo(int_data + 2 * x, 1, 0); else { char buf[128]; sprintf(buf, "%lu", x); assign(buf, -1, false); } } String::String(double x) { char buf[128]; int len = sprintf(buf, "%.12g", x); assign(buf, len, false); } String String::make_claim(char *str, int len, int capacity) { assert(str && len > 0 && capacity >= len); memo_t *new_memo = create_memo(str - MEMO_SPACE, len, capacity); return String(str, len, new_memo); } String String::make_stable(const char *s, int len) { if (len < 0) len = (s ? strlen(s) : 0); return String(s, len, 0); } String String::make_fill(int c, int len) { String s; s.append_fill(c, len); return s; } void String::assign_out_of_memory() { if (_r.memo) deref(); _r.memo = 0; _r.data = &oom_data; _r.length = 0; } void String::assign(const char *s, int len, bool need_deref) { if (!s) { assert(len <= 0); len = 0; } else if (len < 0) len = strlen(s); // need to start with dereference if (need_deref) { if (unlikely(_r.memo && s >= _r.memo->real_data && s + len <= _r.memo->real_data + _r.memo->capacity)) { // Be careful about "String s = ...; s = s.c_str();" _r.data = s; _r.length = len; return; } else deref(); } if (len == 0) { _r.memo = 0; _r.data = (s == &oom_data ? s : &null_data); } else { // Make the memo a multiple of 16 characters and bigger than 'len'. int memo_capacity = (len + 15 + MEMO_SPACE) & ~15; _r.memo = create_memo(0, len, memo_capacity - MEMO_SPACE); if (!_r.memo) { assign_out_of_memory(); return; } memcpy(_r.memo->real_data, s, len); _r.data = _r.memo->real_data; } _r.length = len; } /** @brief Append @a len unknown characters to this string. * @return Modifiable pointer to the appended characters. * * The caller may safely modify the returned memory. Null is returned if * the string becomes out-of-memory. */ char * String::append_uninitialized(int len) { // Appending anything to "out of memory" leaves it as "out of memory" if (unlikely(len <= 0) || out_of_memory()) return 0; // If we can, append into unused space. First, we check that there's // enough unused space for 'len' characters to fit; then, we check // that the unused space immediately follows the data in '*this'. uint32_t dirty; if (_r.memo && ((dirty = _r.memo->dirty), _r.memo->capacity > dirty + len)) { char *real_dirty = _r.memo->real_data + dirty; if (real_dirty == _r.data + _r.length) { _r.memo->dirty = dirty + len; _r.length += len; assert(_r.memo->dirty < _r.memo->capacity); #if HAVE_STRING_PROFILING profile_update_memo_dirty(_r.memo, dirty, dirty + len, _r.memo->capacity); #endif return real_dirty; } } // Now we have to make new space. Make sure the memo is a multiple of 16 // bytes and that it is at least 16. But for large strings, allocate a // power of 2, since power-of-2 sizes minimize waste in frequently-used // allocators, like Linux kmalloc. int want_memo_len = _r.length + len + MEMO_SPACE; int memo_capacity; if (want_memo_len <= 1024) memo_capacity = (want_memo_len + 15) & ~15; else for (memo_capacity = 2048; memo_capacity < want_memo_len; ) memo_capacity *= 2; memo_t *new_memo = create_memo(0, _r.length + len, memo_capacity - MEMO_SPACE); if (!new_memo) { assign_out_of_memory(); return 0; } char *new_data = new_memo->real_data; memcpy(new_data, _r.data, _r.length); deref(); _r.data = new_data; new_data += _r.length; // now new_data points to the garbage _r.length += len; _r.memo = new_memo; return new_data; } void String::append(const char *s, int len, memo_t *memo) { if (!s) { assert(len <= 0); len = 0; } else if (len < 0) len = strlen(s); if (s == &oom_data) // Appending "out of memory" to a regular string makes it "out of // memory" assign_out_of_memory(); else if (len == 0) /* do nothing */; else if (_r.length == 0 && memo && !out_of_memory()) { deref(); assign_memo(s, len, memo); } else if (likely(!(_r.memo && s >= _r.memo->real_data && s + len <= _r.memo->real_data + _r.memo->capacity))) { if (char *space = append_uninitialized(len)) memcpy(space, s, len); } else { String preserve_s(*this); if (char *space = append_uninitialized(len)) memcpy(space, s, len); } } /** @brief Append @a len copies of character @a c to this string. */ void String::append_fill(int c, int len) { assert(len >= 0); if (char *space = append_uninitialized(len)) memset(space, c, len); } /** @brief Ensure the string's data is unshared and return a mutable pointer to it. */ char * String::mutable_data() { // If _memo has a capacity (it's not one of the special strings) and it's // uniquely referenced, return _data right away. if (_r.memo && _r.memo->refcount == 1) return const_cast(_r.data); // Otherwise, make a copy of it. Rely on: deref() doesn't change _data or // _length; and if _capacity == 0, then deref() doesn't free _real_data. assert(!_r.memo || _r.memo->refcount > 1); // But in multithreaded situations we must hold a local copy of memo! String do_not_delete_underlying_memo(*this); deref(); assign(_r.data, _r.length, false); return const_cast(_r.data); } char * String::mutable_c_str() { (void) mutable_data(); (void) c_str(); return const_cast(_r.data); } /** @brief Return a substring of this string, consisting of the @a len characters starting at index @a pos. @param pos substring's first position relative to the string @param len length of substring If @a pos is negative, starts that far from the end of the string. If @a len is negative, leaves that many characters off the end of the string. If @a pos and @a len specify a substring that is partly outside the string, only the part within the string is returned. If the substring is beyond either end of the string, returns an empty string (but this should be considered a programming error; a future version may generate a warning for this case). @note String::substring() is intended to behave like Perl's substr(). */ String String::substring(int pos, int len) const { if (pos < 0) pos += _r.length; int pos2; if (len < 0) pos2 = _r.length + len; else if (pos >= 0 && len >= _r.length) // avoid integer overflow pos2 = _r.length; else pos2 = pos + len; if (pos < 0) pos = 0; if (pos2 > _r.length) pos2 = _r.length; if (pos >= pos2) return String(); else return String(_r.data + pos, pos2 - pos, _r.memo); } int String::find_left(char c, int start) const { if (start < 0) start = 0; for (int i = start; i < _r.length; i++) if (_r.data[i] == c) return i; return -1; } int String::find_left(const String &str, int start) const { if (start < 0) start = 0; int max_pos = length() - str.length(); for (int i = start; i <= max_pos; ++i) if (memcmp(_r.data + i, str.data(), str.length()) == 0) return i; return -1; } int String::find_right(char c, int start) const { if (start >= _r.length) start = _r.length - 1; for (int i = start; i >= 0; i--) if (_r.data[i] == c) return i; return -1; } static String hard_lower(const String &s, int pos) { String new_s(s.data(), s.length()); char *x = const_cast(new_s.data()); // know it's mutable int len = s.length(); for (; pos < len; pos++) x[pos] = tolower((unsigned char) x[pos]); return new_s; } /** @brief Return a lowercased version of this string. Translates the ASCII characters 'A' through 'Z' into their lowercase equivalents. */ String String::lower() const { // avoid copies if (!out_of_memory()) for (int i = 0; i < _r.length; i++) if (_r.data[i] >= 'A' && _r.data[i] <= 'Z') return hard_lower(*this, i); return *this; } static String hard_upper(const String &s, int pos) { String new_s(s.data(), s.length()); char *x = const_cast(new_s.data()); // know it's mutable int len = s.length(); for (; pos < len; pos++) x[pos] = toupper((unsigned char) x[pos]); return new_s; } /** @brief Return an uppercased version of this string. Translates the ASCII characters 'a' through 'z' into their uppercase equivalents. */ String String::upper() const { // avoid copies for (int i = 0; i < _r.length; i++) if (_r.data[i] >= 'a' && _r.data[i] <= 'z') return hard_upper(*this, i); return *this; } static String hard_printable(const String &s, int pos, int type) { StringAccum sa(s.length() * 2); sa.append(s.data(), pos); const unsigned char *x = reinterpret_cast(s.data()); int len = s.length(); for (; pos < len; pos++) { if (x[pos] >= 32 && x[pos] < 127) sa << x[pos]; else if (x[pos] < 32 && type != 1) sa << '^' << (unsigned char)(x[pos] + 64); else if (char *buf = sa.extend(4, 1)) sprintf(buf, "\\%03o", x[pos]); } return sa.take_string(); } /** @brief Return a "printable" version of this string. @param type quoting type The default quoting type (0) translates control characters 0-31 into "control" sequences, such as "^@" for the null character, and characters 127-255 into octal escape sequences, such as "\377" for 255. Quoting type 1 translates all characters outside of 32-126 into octal escape sequences. */ String String::printable(int type) const { // avoid copies if (!out_of_memory()) for (int i = 0; i < _r.length; i++) if (_r.data[i] < 32 || _r.data[i] > 126) return hard_printable(*this, i, type); return *this; } hashcode_t String::hashcode(const char *begin, const char *end) { if (end <= begin) return 0; uint32_t hash = end - begin; int rem = hash & 3; end -= rem; uint32_t last16; #if !HAVE_INDIFFERENT_ALIGNMENT if (!(reinterpret_cast(begin) & 1)) { #endif #define get16(p) (*reinterpret_cast((p))) for (; begin != end; begin += 4) { hash += get16(begin); uint32_t tmp = (get16(begin + 2) << 11) ^ hash; hash = (hash << 16) ^ tmp; hash += hash >> 11; } if (rem >= 2) { last16 = get16(begin); goto rem2; } #undef get16 #if !HAVE_INDIFFERENT_ALIGNMENT } else { # if WORDS_BIGENDIAN # define get16(p) (((unsigned char) (p)[0] << 8) + (unsigned char) (p)[1]) # elif WORDS_BIGENDIAN_SET # define get16(p) ((unsigned char) (p)[0] + ((unsigned char) (p)[1] << 8)) # else # error "unknown byte order" # endif // should be exactly the same as the code above for (; begin != end; begin += 4) { hash += get16(begin); uint32_t tmp = (get16(begin + 2) << 11) ^ hash; hash = (hash << 16) ^ tmp; hash += hash >> 11; } if (rem >= 2) { last16 = get16(begin); goto rem2; } # undef get16 } #endif /* Handle end cases */ if (0) { // weird organization avoids uninitialized rem2: // variable warnings if (rem == 3) { hash += last16; hash ^= hash << 16; hash ^= ((unsigned char) begin[2]) << 18; hash += hash >> 11; } else { hash += last16; hash ^= hash << 11; hash += hash >> 17; } } else if (rem == 1) { hash += (unsigned char) *begin; hash ^= hash << 10; hash += hash >> 1; } /* Force "avalanching" of final 127 bits */ hash ^= hash << 3; hash += hash >> 5; hash ^= hash << 4; hash += hash >> 17; hash ^= hash << 25; hash += hash >> 6; return hash; } #if 0 // 11.Apr.2008 -- This old hash function was swapped out in favor of // SuperFastHash, above. hashcode_t String::hashcode() const { int l = length(); const char *d = data(); if (!l) return 0; else if (l == 1) return d[0] | (d[0] << 8); else if (l < 4) return d[0] + (d[1] << 3) + (l << 12); else return d[0] + (d[1] << 8) + (d[2] << 16) + (d[3] << 24) + (l << 12) + (d[l-1] << 10); } #endif bool String::equals(const char *s, int len) const { // It'd be nice to make "out-of-memory" strings compare unequal to // anything, even themselves, but this would be a bad idea for Strings // used as (for example) keys in hashtables. Instead, "out-of-memory" // strings compare unequal to other null strings, but equal to each other. if (len < 0) len = strlen(s); if (_r.length != len) return false; else if (_r.data == s) return true; else if (len == 0) return (s != &oom_data && _r.data != &oom_data); else return memcmp(_r.data, s, len) == 0; } bool String::starts_with(const char *s, int len) const { // See note on equals() re: "out-of-memory" strings. if (len < 0) len = strlen(s); if (_r.length < len) return false; else if (_r.data == s) return true; else if (len == 0) return (s != &oom_data && _r.data != &oom_data); else return memcmp(_r.data, s, len) == 0; } int String::compare(const char *s, int len) const { if (len < 0) len = strlen(s); if (_r.data == s) return _r.length - len; else if (_r.data == &oom_data) return 1; else if (s == &oom_data) return -1; else if (_r.length == len) return memcmp(_r.data, s, len); else if (_r.length < len) { int v = memcmp(_r.data, s, _r.length); return (v ? v : -1); } else { int v = memcmp(_r.data, s, len); return (v ? v : 1); } } void String::align(int n) { int offset = reinterpret_cast(_r.data) % n; if (offset) { String s; s.append_uninitialized(_r.length + n + 1); offset = reinterpret_cast(s._r.data) % n; memcpy((char *)s._r.data + n - offset, _r.data, _r.length); s._r.data += n - offset; s._r.length = _r.length; *this = s; } } lcdf-typetools-2.108/liblcdf/md5.c0000664000175000017500000002267212732752520013665 00000000000000/* -*- mode: c; c-basic-offset: 8; related-file-name: "../include/lcdf/md5.h" -*- */ /* md5.c - MD5 Message-Digest Algorithm * Copyright (C) 1995, 1996, 1998, 1999 Free Software Foundation, Inc. * * according to the definition of MD5 in RFC 1321 from April 1992. * NOTE: This is *not* the same file as the one from glibc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Written by Ulrich Drepper , 1995. */ /* heavily modified for GnuPG by */ /* modified again for Sylpheed by 2001-02-11 */ /* modified again for LCDF by Eddie Kohler */ /* Test values: * "" D4 1D 8C D9 8F 00 B2 04 E9 80 09 98 EC F8 42 7E * "a" 0C C1 75 B9 C0 F1 B6 A8 31 C3 99 E2 69 77 26 61 * "abc 90 01 50 98 3C D2 4F B0 D6 96 3F 7D 28 E1 7F 72 * "message digest" F9 6B 69 7D 7C B7 93 8D 52 5A 2F 31 AA F1 61 D0 */ #include #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif /**************** * Rotate a 32 bit integer by n bits */ #if defined(__GNUC__) && defined(__i386__) static inline uint32_t rol( uint32_t x, int n) { __asm__("roll %%cl,%0" :"=r" (x) :"0" (x),"c" (n)); return x; } #else #define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) ) #endif void md5_init(MD5_CONTEXT *ctx) { ctx->A = 0x67452301; ctx->B = 0xefcdab89; ctx->C = 0x98badcfe; ctx->D = 0x10325476; ctx->nblocks = 0; ctx->count = 0; ctx->finalized = 0; } /* These are the four functions used in the four steps of the MD5 algorithm and defined in the RFC 1321. The first function is a little bit optimized (as found in Colin Plumbs public domain implementation). */ /* #define FF(b, c, d) ((b & c) | (~b & d)) */ #define FF(b, c, d) (d ^ (b & (c ^ d))) #define FG(b, c, d) FF (d, b, c) #define FH(b, c, d) (b ^ c ^ d) #define FI(b, c, d) (c ^ (b | ~d)) /**************** * transform n*64 bytes */ static void transform(MD5_CONTEXT *ctx, const unsigned char *data) { uint32_t correct_words[16]; uint32_t A = ctx->A; uint32_t B = ctx->B; uint32_t C = ctx->C; uint32_t D = ctx->D; uint32_t *cwp = correct_words; #if WORDS_BIGENDIAN { int i; unsigned char *p2, *p1; for (i = 0, p1 = data, p2 = (unsigned char*)correct_words; i < 16; i++, p2 += 4) { p2[3] = *p1++; p2[2] = *p1++; p2[1] = *p1++; p2[0] = *p1++; } } #elif WORDS_BIGENDIAN_SET memcpy(correct_words, data, 64); #else # error "WORDS_BIGENDIAN has not been set!" #endif #define OP(a, b, c, d, s, T) \ do { \ a += FF (b, c, d) + (*cwp++) + T; \ a = rol(a, s); \ a += b; \ } while (0) /* Before we start, one word about the strange constants. They are defined in RFC 1321 as T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 */ /* Round 1. */ OP (A, B, C, D, 7, 0xd76aa478); OP (D, A, B, C, 12, 0xe8c7b756); OP (C, D, A, B, 17, 0x242070db); OP (B, C, D, A, 22, 0xc1bdceee); OP (A, B, C, D, 7, 0xf57c0faf); OP (D, A, B, C, 12, 0x4787c62a); OP (C, D, A, B, 17, 0xa8304613); OP (B, C, D, A, 22, 0xfd469501); OP (A, B, C, D, 7, 0x698098d8); OP (D, A, B, C, 12, 0x8b44f7af); OP (C, D, A, B, 17, 0xffff5bb1); OP (B, C, D, A, 22, 0x895cd7be); OP (A, B, C, D, 7, 0x6b901122); OP (D, A, B, C, 12, 0xfd987193); OP (C, D, A, B, 17, 0xa679438e); OP (B, C, D, A, 22, 0x49b40821); #undef OP #define OP(f, a, b, c, d, k, s, T) \ do { \ a += f (b, c, d) + correct_words[k] + T; \ a = rol(a, s); \ a += b; \ } while (0) /* Round 2. */ OP (FG, A, B, C, D, 1, 5, 0xf61e2562); OP (FG, D, A, B, C, 6, 9, 0xc040b340); OP (FG, C, D, A, B, 11, 14, 0x265e5a51); OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa); OP (FG, A, B, C, D, 5, 5, 0xd62f105d); OP (FG, D, A, B, C, 10, 9, 0x02441453); OP (FG, C, D, A, B, 15, 14, 0xd8a1e681); OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8); OP (FG, A, B, C, D, 9, 5, 0x21e1cde6); OP (FG, D, A, B, C, 14, 9, 0xc33707d6); OP (FG, C, D, A, B, 3, 14, 0xf4d50d87); OP (FG, B, C, D, A, 8, 20, 0x455a14ed); OP (FG, A, B, C, D, 13, 5, 0xa9e3e905); OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8); OP (FG, C, D, A, B, 7, 14, 0x676f02d9); OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a); /* Round 3. */ OP (FH, A, B, C, D, 5, 4, 0xfffa3942); OP (FH, D, A, B, C, 8, 11, 0x8771f681); OP (FH, C, D, A, B, 11, 16, 0x6d9d6122); OP (FH, B, C, D, A, 14, 23, 0xfde5380c); OP (FH, A, B, C, D, 1, 4, 0xa4beea44); OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9); OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60); OP (FH, B, C, D, A, 10, 23, 0xbebfbc70); OP (FH, A, B, C, D, 13, 4, 0x289b7ec6); OP (FH, D, A, B, C, 0, 11, 0xeaa127fa); OP (FH, C, D, A, B, 3, 16, 0xd4ef3085); OP (FH, B, C, D, A, 6, 23, 0x04881d05); OP (FH, A, B, C, D, 9, 4, 0xd9d4d039); OP (FH, D, A, B, C, 12, 11, 0xe6db99e5); OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8); OP (FH, B, C, D, A, 2, 23, 0xc4ac5665); /* Round 4. */ OP (FI, A, B, C, D, 0, 6, 0xf4292244); OP (FI, D, A, B, C, 7, 10, 0x432aff97); OP (FI, C, D, A, B, 14, 15, 0xab9423a7); OP (FI, B, C, D, A, 5, 21, 0xfc93a039); OP (FI, A, B, C, D, 12, 6, 0x655b59c3); OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92); OP (FI, C, D, A, B, 10, 15, 0xffeff47d); OP (FI, B, C, D, A, 1, 21, 0x85845dd1); OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f); OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0); OP (FI, C, D, A, B, 6, 15, 0xa3014314); OP (FI, B, C, D, A, 13, 21, 0x4e0811a1); OP (FI, A, B, C, D, 4, 6, 0xf7537e82); OP (FI, D, A, B, C, 11, 10, 0xbd3af235); OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb); OP (FI, B, C, D, A, 9, 21, 0xeb86d391); /* Put checksum in context given as argument. */ ctx->A += A; ctx->B += B; ctx->C += C; ctx->D += D; } /* The routine updates the message-digest context to * account for the presence of each of the characters inBuf[0..inLen-1] * in the message whose digest is being computed. */ void md5_update(MD5_CONTEXT *hd, const unsigned char *inbuf, size_t inlen) { if (hd->count == 64) { /* flush the buffer */ transform( hd, hd->buf ); hd->count = 0; hd->nblocks++; } if (!inbuf) return; if (hd->count) { for (; inlen && hd->count < 64; inlen--) hd->buf[hd->count++] = *inbuf++; md5_update(hd, NULL, 0); if (!inlen) return; } while (inlen >= 64) { transform(hd, inbuf); hd->count = 0; hd->nblocks++; inlen -= 64; inbuf += 64; } for (; inlen && hd->count < 64; inlen--) hd->buf[hd->count++] = *inbuf++; } /* The routine final terminates the message-digest computation and * ends with the desired message digest in mdContext->digest[0...15]. * The handle is prepared for a new MD5 cycle. * Returns 16 bytes representing the digest. */ static void do_final(MD5_CONTEXT *hd) { uint32_t t, msb, lsb; unsigned char *p; md5_update(hd, NULL, 0); /* flush */ msb = 0; t = hd->nblocks; if ((lsb = t << 6) < t) /* multiply by 64 to make a byte count */ msb++; msb += t >> 26; t = lsb; if ((lsb = t + hd->count) < t) /* add the count */ msb++; t = lsb; if ((lsb = t << 3) < t) /* multiply by 8 to make a bit count */ msb++; msb += t >> 29; if (hd->count < 56) { /* enough room */ hd->buf[hd->count++] = 0x80; /* pad */ while(hd->count < 56) hd->buf[hd->count++] = 0; /* pad */ } else { /* need one extra block */ hd->buf[hd->count++] = 0x80; /* pad character */ while (hd->count < 64) hd->buf[hd->count++] = 0; md5_update(hd, NULL, 0); /* flush */ memset(hd->buf, 0, 56); /* fill next block with zeroes */ } /* append the 64 bit count */ hd->buf[56] = lsb ; hd->buf[57] = lsb >> 8; hd->buf[58] = lsb >> 16; hd->buf[59] = lsb >> 24; hd->buf[60] = msb ; hd->buf[61] = msb >> 8; hd->buf[62] = msb >> 16; hd->buf[63] = msb >> 24; transform(hd, hd->buf); p = hd->buf; #if WORDS_BIGENDIAN #define X(a) do { *p++ = hd->a ; *p++ = hd->a >> 8; \ *p++ = hd->a >> 16; *p++ = hd->a >> 24; } while(0) #elif WORDS_BIGENDIAN_SET /*#define X(a) do { *(uint32_t*)p = hd->##a ; p += 4; } while(0)*/ /* Unixware's cpp doesn't like the above construct so we do it his way: * (reported by Allan Clark) */ #define X(a) do { *(uint32_t*)p = (*hd).a ; p += 4; } while(0) #else # error "WORDS_BIGENDIAN has not been set!" #endif X(A); X(B); X(C); X(D); #undef X hd->finalized = 1; } void md5_final(unsigned char *digest, MD5_CONTEXT *ctx) { if (!ctx->finalized) do_final(ctx); memcpy(digest, ctx->buf, 16); } void md5_final_text(char *buf, MD5_CONTEXT *ctx) { static const char *chars = "abcdefghijklmnopqrstuvwxyz234567"; int bit; if (!ctx->finalized) do_final(ctx); for (bit = 0; bit < 16*8; bit += 5) { int first_char = bit / 8; int val = ctx->buf[first_char] >> (bit % 8); if (bit + 8 > (first_char + 1) * 8 && first_char < 15) val += ctx->buf[first_char + 1] << (8 - (bit % 8)); *buf++ = chars[val & 0x1F]; } *buf++ = 0; } #ifdef __cplusplus } #endif lcdf-typetools-2.108/liblcdf/point.cc0000644000175000017500000000276213423375327014474 00000000000000// -*- related-file-name: "../include/lcdf/point.hh" -*- /* point.{cc,hh} -- 2D points * * Copyright (c) 1998-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include Point Point::rotated(double rotation) const noexcept { double r = length(); double theta = angle() + rotation; return Point(r * cos(theta), r * sin(theta)); } Point Point::midpoint(const Point &a, const Point &b) noexcept { return Point((a.x + b.x)/2, (a.y + b.y)/2); } bool Point::on_line(const Point &a, const Point &b, double tolerance) const noexcept { Point c = b - a; double d = c.x * (y - a.y) - c.y * (x - a.x); return (d * d <= tolerance * tolerance * c.squared_length()); } bool Point::on_segment(const Point &a, const Point &b, double t) const noexcept { double tt; Point c = b - a; if (fabs(c.x) > fabs(c.y)) tt = (x - a.x) / c.x; else if (c.y) tt = (y - a.y) / c.y; else tt = 0; if (tt < 0 || tt > 1) return 0; return on_line(a, b, t); } lcdf-typetools-2.108/liblcdf/Makefile.am0000664000175000017500000000100612732752520015054 00000000000000## Process this file with automake to produce Makefile.in AUTOMAKE_OPTIONS = foreign noinst_LIBRARIES = liblcdf.a liblcdf_a_SOURCES = bezier.cc \ clp.c \ error.cc \ filename.cc \ globmatch.cc \ landmark.cc \ md5.c \ permstr.cc \ point.cc \ slurper.cc \ straccum.cc \ string.cc \ strtonum.c \ transform.cc \ vectorv.cc if FIXLIBC liblcdf_a_SOURCES += fixlibc.c endif FIXLIBC liblcdf_a_LIBADD = @TEMPLATE_OBJS@ CLEANFILES = @TEMPLATE_OBJS@ AM_CPPFLAGS = -I$(srcdir)/../include EXTRA_DIST = fixlibc.c lcdf-typetools-2.108/configure.ac0000644000175000017500000003563613423376565013736 00000000000000dnl Process this file with autoconf to produce a configure script. AC_INIT([lcdf-typetools], [2.108]) AC_CONFIG_SRCDIR([NEWS.md]) AM_INIT_AUTOMAKE AC_CONFIG_HEADERS([autoconf.h]) AM_MAINTAINER_MODE AC_PROG_MAKE_SET AC_PROG_CC AC_PROG_CPP AC_PROG_CXX AC_PROG_CXXCPP AC_ARG_ENABLE([warnings], [AS_HELP_STRING([--enable-warnings], [compile with -W -Wall])], [if test "$enableval" = yes; then CFLAGS="$CFLAGS -W -Wall"; CXXFLAGS="$CXXFLAGS -W -Wall" fi]) AC_ARG_ENABLE([precondition-checking], [AS_HELP_STRING([--enable-precondition-checking], [include precondition checking assertions])], [if test "$enableval" = yes; then AC_DEFINE([HAVE_PRECONDITION_CHECKING], [1], [Define to include precondition checking assertions.]) fi]) AC_ARG_ENABLE([adobe-code], [AS_HELP_STRING([--disable-adobe-code], [do not include Adobe code])], [], [enable_adobe_code=yes]) if test "$enable_adobe_code" = yes; then AC_DEFINE([HAVE_ADOBE_CODE], [1], [Define to incldue Adobe code in output fonts.]) fi dnl AN_MAKEVAR([AR], [AC_PROG_AR]) dnl AN_PROGRAM([ar], [AC_PROG_AR]) dnl AC_DEFUN([AC_PROG_AR], [AC_CHECK_TOOL(AR, ar, :)]) dnl AC_PROG_AR AC_PROG_RANLIB dnl Available from the GNU Autoconf Macro Archive at: dnl http://www.gnu.org/software/ac-archive/htmldoc/ac_cxx_template_objs.html dnl AC_DEFUN([AC_CXX_TEMPLATE_OBJS], [AC_CACHE_CHECK(where template objects are stored, ac_cv_cxx_templobjs, [ ac_cv_cxx_templobjs='unknown' if test "$GXX" = yes; then ac_cv_cxx_templobjs='nowhere' else case $CXX in CC|*/CC) cat > conftest.cc < class A { public : A () {} }; template void f (const A&) {} main() { A d; A i; f (d); f (i); return 0; } EOF if test "$ac_cv_cxx_templobjs" = 'unknown' ; then if test -d Templates.DB ; then rm -fr Templates.DB fi if $CXX $CXXFLAGS -ptr. -c conftest.cc 1> /dev/null 2>&1; then if test -d Templates.DB ; then # this should be Sun CC <= 4.2 CXXFLAGS="$CXXFLAGS -ptr." if test x"$LIBTOOL" = x ; then ac_cv_cxx_templobjs='Templates.DB/*.o' else ac_cv_cxx_templobjs='Templates.DB/*.lo' fi rm -fr Templates.DB fi fi fi if test "$ac_cv_cxx_templobjs" = 'unknown' ; then if test -d SunWS_cache ; then rm -fr SunWS_cache fi if $CXX $CXXFLAGS -c conftest.cc 1> /dev/null 2>&1; then if test -d SunWS_cache ; then # this should be Sun WorkShop C++ compiler 5.x # or Sun Forte C++ compiler >= 6.x if test x"$LIBTOOL" = x ; then ac_cv_cxx_templobjs='SunWS_cache/*/*.o' else ac_cv_cxx_templobjs='SunWS_cache/*/*.lo' fi rm -fr SunWS_cache fi fi fi rm -f conftest* ;; esac fi case "x$ac_cv_cxx_templobjs" in xunknown|xnowhere) TEMPLATE_OBJS="" ;; *) TEMPLATE_OBJS="$ac_cv_cxx_templobjs" ;; esac]) AC_SUBST(TEMPLATE_OBJS)]) AC_CXX_TEMPLATE_OBJS dnl dnl standard headers dnl (Though obsolete, AC_HEADER_STC changes the standard includes.) dnl AC_LANG_C AC_HEADER_STDC AC_HEADER_DIRENT AC_CHECK_HEADERS([fcntl.h unistd.h sys/time.h sys/wait.h]) dnl dnl and/or dnl AC_LANG_CPLUSPLUS AC_CACHE_CHECK([whether works], ac_cv_good_new_hdr, [AC_TRY_LINK([#include ], [ int a; int *b = new(&a) int; return 0; ], ac_cv_good_new_hdr=yes, ac_cv_good_new_hdr=no)]) if test "$ac_cv_good_new_hdr" = yes; then AC_DEFINE([HAVE_NEW_HDR], [1], [Define if exists and works.]) fi AC_CHECK_HEADERS([new.h]) dnl dnl endianness dnl AC_DEFINE([WORDS_BIGENDIAN_SET], [1], [Define if WORDS_BIGENDIAN has been set.]) AC_C_BIGENDIAN() dnl dnl functions such as strerror, working strtod, working strnlen, strtoul, dnl time headers such as unistd.h dnl AC_LANG_C need_fixlibc=0 AC_CHECK_FUNCS([strerror], [], [need_fixlibc=1]) AC_CACHE_CHECK([for broken strtod], [ac_cv_broken_strtod], [AC_TRY_RUN([#include #include int main(int c, char **v) { char s[] = "12 "; char *endp; double d = strtod(s, &endp); return (s + 2) == endp; }], [ac_cv_broken_strtod=yes], [ac_cv_broken_strtod=no], [ac_cv_broken_strtod=no])]) if test "x$ac_cv_broken_strtod" = xyes; then need_fixlibc=1 AC_DEFINE([HAVE_BROKEN_STRTOD], [1], [Define if strtod is broken.]) fi AC_LANG_CPLUSPLUS AC_CHECK_DECLS([strnlen], [], [], [#include ]) AC_CHECK_FUNCS([strnlen], [have_strnlen=1], [need_fixlibc=1]) if test "x$have_strnlen" = x1; then AC_CACHE_CHECK([for broken strnlen], [ac_cv_broken_strnlen], [AC_TRY_RUN([#include #include int main(int c, char **v) { char s[] = "01234567891"; return strnlen(s, 10) == 10; }], [ac_cv_broken_strnlen=yes], [ac_cv_broken_strnlen=no], [ac_cv_broken_strnlen=no])]) if test "x$ac_cv_broken_strnlen" = xyes; then need_fixlibc=1 AC_DEFINE([HAVE_BROKEN_STRNLEN], [1], [Define if strnlen is broken.]) fi fi AC_LANG_C AC_CHECK_FUNCS([ctime ftruncate mkstemp sigaction strdup strtoul vsnprintf waitpid]) AC_CHECK_FUNC([floor], [], [AC_CHECK_LIB([m], [floor])]) AC_CHECK_FUNC([fabs], [], [AC_CHECK_LIB([m], [fabs])]) AM_CONDITIONAL([FIXLIBC], [test x$need_fixlibc = x1]) dnl dnl integer types dnl AC_CHECK_HEADERS(inttypes.h, have_inttypes_h=yes, have_inttypes_h=no) AC_CHECK_HEADERS(sys/types.h, have_sys_types_h=yes, have_sys_types_h=no) if test $have_inttypes_h = no -a $have_sys_types_h = yes; then AC_CACHE_CHECK([for uintXX_t typedefs], ac_cv_uint_t, [AC_EGREP_HEADER(dnl changequote(<<,>>)<<(^|[^a-zA-Z_0-9])uint32_t[^a-zA-Z_0-9]>>changequote([,]), sys/types.h, ac_cv_uint_t=yes, ac_cv_uint_t=no)]) fi if test $have_inttypes_h = no -a $have_sys_types_h = yes -a "$ac_cv_uint_t" = no; then AC_CACHE_CHECK([for u_intXX_t typedefs], ac_cv_u_int_t, [AC_EGREP_HEADER(dnl changequote(<<,>>)<<(^|[^a-zA-Z_0-9])u_int32_t[^a-zA-Z_0-9]>>changequote([,]), sys/types.h, ac_cv_u_int_t=yes, ac_cv_u_int_t=no)]) fi if test $have_inttypes_h = yes -o "$ac_cv_uint_t" = yes; then : elif test "$ac_cv_u_int_t" = yes; then AC_DEFINE(HAVE_U_INT_TYPES, 1, [Define if you have u_intXX_t types but not uintXX_t types.]) else AC_MSG_WARN([ ========================================= Neither uint32_t nor u_int32_t defined by or ! Assuming "short" has 16 bits and "int" has 32 bits. =========================================]) AC_DEFINE(HAVE_FAKE_INT_TYPES, 1, [Define if intXX_t types are not available.]) fi AC_CHECK_TYPES(uintptr_t, [], [], [#if HAVE_INTTYPES_H # include #endif #if HAVE_SYS_TYPES_H # include #endif ]) AC_CHECK_SIZEOF(void *) AC_CHECK_SIZEOF(unsigned long) AC_CHECK_SIZEOF(unsigned int) dnl dnl ntohs, ntohl (need them in C++ code) dnl AC_LANG_CPLUSPLUS AC_CHECK_HEADERS([byteorder.h netinet/in.h sys/param.h]) AC_MSG_CHECKING([whether ntohs and ntohl are defined]) ac_ntoh_defined=no AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[#if HAVE_SYS_TYPES_H # include #endif #if HAVE_BYTEORDER_H # include #elif HAVE_NETINET_IN_H # include #elif HAVE_SYS_PARAM_H # include #endif #ifdef WIN32 # ifdef __MSC_VER # pragma warning (disable: 4290) # endif # include #endif ]], [[(void) ntohs(0x0020), (void) ntohl(0x03040020);]])], [AC_MSG_RESULT(yes) ac_ntoh_defined=yes], [AC_MSG_RESULT(no)]) if test $ac_ntoh_defined = no; then AC_CHECK_HEADERS([arpa/inet.h], [have_arpa_inet_h=yes], [have_arpa_inet_h=no]) if test $have_arpa_inet_h = yes; then AC_MSG_CHECKING([whether ntohs and ntohl are defined in ]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[#if HAVE_SYS_TYPES_H # include #endif #include ]], [[(void) ntohs(0x0020), (void) ntohl(0x03040020);]])], [AC_MSG_RESULT(yes) AC_DEFINE(NEED_ARPA_INET_H, 1, [Define to 1 if you must include to get `ntohl'.]) ac_ntoh_defined=yes], [AC_MSG_RESULT(no)]) fi fi if test $ac_ntoh_defined = no; then AC_MSG_ERROR([ ========================================= Cannot find a definition for ntohs and/or ntohl! =========================================]) fi AC_LANG_C AC_SEARCH_LIBS([ntohs], [-lnet -lwinsock32]) dnl dnl is va_list addressable? dnl AC_LANG_CPLUSPLUS AC_CACHE_CHECK([for addressable va_list type], ac_cv_va_list_addr, [AC_TRY_COMPILE([#include void f(va_list *) { } void g(va_list val) { f(&val); } void h(int a, ...) { va_list val; va_start(val, a); g(val); va_end(val); }], [h(2, 3, 4);], ac_cv_va_list_addr=yes, ac_cv_va_list_addr=no)]) if test "x$ac_cv_va_list_addr" = xyes; then AC_DEFINE(HAVE_ADDRESSABLE_VA_LIST, 1, [Define if the va_list type is addressable.]) fi dnl dnl select programs to be compiled and automatically run dnl m4_include([m4/lcdf-typetools.m4]) SELECTED_SUBDIRS= AC_FOREACH([Kpse_Prog], kpse_lcdf_typetools_progs, [test "x$enable_[]Kpse_Prog" = xno || SELECTED_SUBDIRS="$SELECTED_SUBDIRS Kpse_Prog" ]) AC_SUBST(SELECTED_SUBDIRS) AC_FOREACH([Kpse_Opt], kpse_otftotfm_auto_opts, [AS_IF([test "x$enable_auto_]Kpse_Opt[" != xno], [AC_DEFINE([HAVE_AUTO_]AS_TR_CPP(Kpse_Opt), 1, [Define to run ]Kpse_Opt[ from otftotfm.])]) ]) dnl dnl kpathsea dnl AC_ARG_WITH([kpathsea], [AS_HELP_STRING([--with-kpathsea=PREFIX], [Kpathsea is installed (under PREFIX)])], [kpathsea=$withval], [kpathsea=]) KPATHSEA_INCLUDES= KPATHSEA_LIBS= KPATHSEA_DEPEND= if test "x$kpathsea" != xno; then SAVE_CPPFLAGS="$CPPFLAGS"; SAVE_LDFLAGS="$LDFLAGS" if test "x$kpathsea" != x -a "x$kpathsea" != xyes; then KPATHSEA_INCLUDES="-I$kpathsea/include" KPATHSEA_LIBS="-L$kpathsea/lib" else kpathsea=yes fi dnl check for kpathsea/kpathsea.h if true; then CPPFLAGS="$SAVE_CPPFLAGS $KPATHSEA_INCLUDES" AC_CHECK_HEADER([kpathsea/kpathsea.h], [kpse_header=yes], [kpse_header=no]) fi dnl if not found and kpathsea prefix not set, check /usr/local if test "x$kpse_header" != xyes -a "x$kpathsea" = xyes -a -r /usr/local/include/kpathsea/tex-file.h; then KPATHSEA_INCLUDES="-I/usr/local/include" KPATHSEA_LIBS="-L/usr/local/lib" CPPFLAGS="$SAVE_CPPFLAGS $KPATHSEA_INCLUDES" AC_CHECK_HEADER([kpathsea/tex-file.h], [kpse_header=yes], [kpse_header=no]) fi dnl check for -lkpathsea if true; then LDFLAGS="$SAVE_LDFLAGS $KPATHSEA_LIBS" AC_CHECK_LIB([kpathsea], [kpse_set_program_name], [kpse_library=yes], [kpse_library=no]) fi dnl bail out if not found if test "x$kpse_header" != xyes -o "x$kpse_library" != xyes; then AC_MSG_ERROR([ ========================================= I can't find the kpathsea library and/or header files. Tell me where to look using the --with-kpathsea=PREFIX option (header files should be under PREFIX/include/kpathsea, and library under PREFIX/lib), or disable support using --without-kpathsea. =========================================]) fi dnl OK, found AC_DEFINE(HAVE_KPATHSEA, 1, [Define if you want to use kpathsea.]) if true; then KPATHSEA_LIBS="$KPATHSEA_LIBS -lkpathsea" fi dnl does it have opentype support? if false; then AC_DEFINE(HAVE_DECL_KPSE_OPENTYPE_FORMAT) else AC_CHECK_DECLS([kpse_opentype_format], [], [], [#include ]) fi dnl does it have a separate format for encoding files? AC_CHECK_DECLS([kpse_enc_format], [], [], [#include ]) CPPFLAGS="$SAVE_CPPFLAGS"; LDFLAGS="$SAVE_LDFLAGS" fi AM_CONDITIONAL([have_kpathsea], [test "x$with_kpathsea" != xno]) AC_SUBST([KPATHSEA_INCLUDES]) AC_SUBST([KPATHSEA_LIBS]) AC_SUBST([KPATHSEA_DEPEND]) AC_ARG_ENABLE([selfauto-set], [AS_HELP_STRING([--disable-selfauto-set], [disable setting SELFAUTO variables from kpsewhich])], [], [enable_selfauto_set=yes]) if test "x$enable_selfauto_set" = xyes -a "x$kpathsea" != xno; then kpsewhich='kpsewhich' test "x$kpathsea" != xyes -a -x "$kpathsea/bin/kpsewhich" && kpsewhich="$kpathsea/bin/kpsewhich" SELFAUTOLOC="`$kpsewhich --expand-var='$SELFAUTOLOC' 2>/dev/null`" SELFAUTODIR="`$kpsewhich --expand-var='$SELFAUTODIR' 2>/dev/null`" SELFAUTOPARENT="`$kpsewhich --expand-var='$SELFAUTOPARENT' 2>/dev/null`" SELFAUTOGRANDPARENT="`$kpsewhich --expand-var='$SELFAUTOGRANDPARENT' 2>/dev/null`" if test -z "$SELFAUTODIR"; then AC_MSG_WARN([ ========================================= Could not extract SELFAUTO variables from $kpsewhich. Either supply the correct PREFIX to --with-kpathsea, or supply --disable-selfauto-loc. =========================================]) fi AC_DEFINE_UNQUOTED([SELFAUTOLOC], "$SELFAUTOLOC", [kpsewhich's $SELFAUTOLOC variable]) AC_DEFINE_UNQUOTED([SELFAUTODIR], "$SELFAUTODIR", [kpsewhich's $SELFAUTODIR variable]) AC_DEFINE_UNQUOTED([SELFAUTOPARENT], "$SELFAUTOPARENT", [kpsewhich's $SELFAUTOPARENT variable]) if test -n "$SELFAUTOGRANDPARENT" -a "$SELFAUTOGRANDPARENT" != '$SELFAUTOGRANDPARENT'; then AC_DEFINE_UNQUOTED([SELFAUTOGRANDPARENT], "$SELFAUTOGRANDPARENT", [kpsewhich's $SELFAUTOGRANDPARENT variable]) fi fi dnl dnl glyphlist.txt and *.enc installation locations dnl AC_ARG_ENABLE([glyphlistdir], [AS_HELP_STRING([--enable-glyphlistdir=DIR], [store glyphlist.txt files in DIR [pkgdatadir]])], [glyphlistdir="$enableval"], [glyphlistdir=NONE]) AC_ARG_ENABLE([encdir], [AS_HELP_STRING([--enable-encdir=DIR], [store encoding files in DIR [pkgdatadir]])], [encdir="$enableval"], [encdir=NONE]) test "x$glyphlistdir" = xNONE -o "x$glyphlistdir" = xno \ -o "x$glyphlistdir" = x && glyphlistdir='${pkgdatadir}' test "x$encdir" = xNONE -o "x$encdir" = xno \ -o "x$encdir" = x && encdir='${pkgdatadir}' AC_SUBST([glyphlistdir]) AC_SUBST([encdir]) dnl dnl TeX Live build stub dnl KPATHSEA_RULE= AC_SUBST([KPATHSEA_RULE]) dnl dnl verbatim portions of the header dnl AC_DEFINE(HAVE_PERMSTRING, 1, [Define if PermStrings are available.]) AC_DEFINE(MMAFM_RUN_MMPFB, 1, [Define to 0 if you don't want mmafm to run mmpfb when it needs to get an intermediate master conversion program.]) dnl PATHNAME_SEPARATOR? dnl dnl set path variables dnl shell_expand () { val=`eval echo '$'"$1"` while echo "x$val" | grep '\$' >/dev/null 2>&1; do val=`eval echo "$val"`; done val=`echo "$val" | sed 's,//*,/,g'` eval "$1='$val'" } dnl Preset $prefix and $exec_prefix. test "x$prefix" = xNONE && prefix=$ac_default_prefix test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' pkgdatadir="${datadir}/$PACKAGE" gdir="$glyphlistdir" for i in data dataroot pkgdata g; do shell_expand ${i}dir; done AC_DEFINE_UNQUOTED([GLYPHLISTDIR], ["$gdir"], [Directory for glyphlist.txt files.]) dnl dnl Output dnl AC_OUTPUT(Makefile liblcdf/Makefile libefont/Makefile cfftot1/Makefile mmafm/Makefile mmpfb/Makefile otfinfo/Makefile otftotfm/Makefile t1dotlessj/Makefile t1lint/Makefile t1rawafm/Makefile t1reencode/Makefile t1testpage/Makefile ttftotype42/Makefile) lcdf-typetools-2.108/ttftotype42/0000755000175000017500000000000013423377073013716 500000000000000lcdf-typetools-2.108/ttftotype42/ttftotype42.cc0000644000175000017500000003001213423375330016343 00000000000000/* ttftotype42.cc -- driver for translating TrueType fonts to Type 42 fonts * * Copyright (c) 2006-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_CTIME # include #endif #if defined(_MSDOS) || defined(_WIN32) # include # include #endif using namespace Efont; #define VERSION_OPT 301 #define HELP_OPT 302 #define QUIET_OPT 303 #define OUTPUT_OPT 306 const Clp_Option options[] = { { "help", 'h', HELP_OPT, 0, 0 }, { "output", 'o', OUTPUT_OPT, Clp_ValString, 0 }, { "quiet", 'q', QUIET_OPT, 0, Clp_Negate }, { "version", 'v', VERSION_OPT, 0, 0 }, }; static const char *program_name; void usage_error(ErrorHandler *errh, const char *error_message, ...) { va_list val; va_start(val, error_message); if (!error_message) errh->message("Usage: %s [OPTIONS] [FONTFILE [OUTPUTFILE]]", program_name); else errh->xmessage(ErrorHandler::e_error, error_message, val); errh->message("Type %s --help for more information.", program_name); exit(1); } void usage() { FileErrorHandler uerrh(stdout); uerrh.message("\ % translates a TrueType or TrueType-flavored OpenType font into\n\ PostScript Type 42 format, which is suitable for inclusion in PostScript\n\ files. The result is usually written to the standard output.\n\ \n\ Usage: %s [OPTIONS] [FONTFILE [OUTPUTFILE]]\n\ \n\ Options:\n\ -o, --output=FILE Write output to FILE.\n\ -q, --quiet Do not generate any error messages.\n\ -h, --help Print this message and exit.\n\ -v, --version Print version number and exit.\n\ \n\ Report bugs to .\n", program_name); } // MAIN // This is the list of tables Adobe recommends be included from the source TTF, // plus the 'cmap' table, which helps to make PDF results searchable. static const char * const t42_tables[] = { "cmap", "cvt ", "fpgm", "glyf", "head", "hhea", "hmtx", "loca", "maxp", "prep", "vhea", "vmtx", 0 }; struct NameId { const char *name; int nameid; }; static const NameId fontinfo_names[] = { { "version", OpenType::Name::N_VERSION }, { "Notice", OpenType::Name::N_TRADEMARK }, { "Copyright", OpenType::Name::N_COPYRIGHT }, { "FullName", OpenType::Name::N_FULLNAME }, { "FamilyName", OpenType::Name::N_FAMILY }, { "Weight", OpenType::Name::N_SUBFAMILY }, { 0, 0 } }; static void fprint_sfnts(FILE *f, const String &data, bool glyf, const OpenType::Font &font) { if (glyf && data.length() >= 65535) { OpenType::Data head = font.table("head"); OpenType::Data loca = font.table("loca"); bool loca_long = (head.length() >= 52 && head.u16(50) != 0); int loca_size = (loca_long ? 4 : 2); uint32_t first_offset = 0; for (int i = 1; i * loca_size < loca.length(); i++) { uint32_t next_offset = (loca_long ? loca.u32(4*i) : loca.u16(2*i) * 2); if (next_offset - first_offset >= 65535) { uint32_t prev_offset = (loca_long ? loca.u32(4*i - 4) : loca.u16(2*i - 2) * 2); fprint_sfnts(f, data.substring(first_offset, prev_offset - first_offset), false, font); first_offset = prev_offset; } } fprint_sfnts(f, data.substring(first_offset), false, font); return; } else if (data.length() >= 65535) { for (int offset = 0; offset < data.length(); ) { int next_offset = offset + 65534; if (next_offset > data.length()) next_offset = data.length(); fprint_sfnts(f, data.substring(offset, next_offset - offset), false, font); offset = next_offset; } return; } fputc('<', f); const uint8_t *s = data.udata(); for (int i = 0; i < data.length(); i++) { if (i && (i % 38) == 0) fputc('\n', f); fputc("0123456789ABCDEF"[(s[i] >> 4) & 0xF], f); fputc("0123456789ABCDEF"[s[i] & 0xF], f); } if ((data.length() % 38) == 0) fputc('\n', f); fputs("00>\n", f); } static void do_file(const char *infn, const char *outfn, ErrorHandler *errh) { FILE *f; if (!infn || strcmp(infn, "-") == 0) { f = stdin; infn = ""; #if defined(_MSDOS) || defined(_WIN32) _setmode(_fileno(f), _O_BINARY); #endif } else if (!(f = fopen(infn, "rb"))) errh->fatal("%s: %s", infn, strerror(errno)); int c = getc(f); ungetc(c, f); if (c == EOF) errh->fatal("%s: empty file", infn); StringAccum sa(150000); int amt; do { if (char *x = sa.reserve(32768)) { amt = fread(x, 1, 32768, f); sa.adjust_length(amt); } else amt = 0; } while (amt != 0); if (!feof(f) || ferror(f)) errh->error("%s: %s", infn, strerror(errno)); if (f != stdin) fclose(f); LandmarkErrorHandler cerrh(errh, infn); OpenType::Font otf(sa.take_string(), &cerrh); if (!otf.ok() || !otf.check_checksums(&cerrh)) return; if (otf.table("CFF")) cerrh.fatal("CFF-flavored OpenType font not suitable for Type 42"); OpenType::Name name(otf.table("name"), &cerrh); OpenType::Data head_data = otf.table("head"); if (!otf.table("glyf") || head_data.length() <= 52 || !name.ok()) cerrh.fatal("font appears to lack required tables"); // create reduced font Vector tags; Vector tables; for (const char * const *table = t42_tables; *table; table++) if (String s = otf.table(*table)) { tags.push_back(*table); tables.push_back(s); } OpenType::Font reduced_font = OpenType::Font::make(true, tags, tables); // output file if (!outfn || strcmp(outfn, "-") == 0) { f = stdout; outfn = ""; #if defined(_MSDOS) || defined(_WIN32) _setmode(_fileno(f), _O_BINARY); #endif } else if (!(f = fopen(outfn, "wb"))) errh->fatal("%s: %s", outfn, strerror(errno)); // fprintf(f, "%%!\n"); // get glyph names TrueTypeBoundsCharstringProgram ttbprog(&otf); Vector gn; ttbprog.glyph_names(gn); OpenType::Post post(otf.table("post")); OpenType::Cmap cmap(otf.table("cmap")); double emunits = head_data.u16(18); // font opener fprintf(f, "%%!PS-TrueTypeFont-65536-%u-1\n", head_data.u32(4)); if (post.ok()) fprintf(f, "%%%%VMusage: %u %u\n", post.mem_type42(false), post.mem_type42(true)); fprintf(f, "11 dict begin\n"); fprintf(f, "/FontName /%s def\n", name.english_name(OpenType::Name::N_POSTSCRIPT).c_str()); fprintf(f, "/FontType 42 def\n"); fprintf(f, "/FontMatrix [1 0 0 1 0 0] def\n"); fprintf(f, "/FontBBox [%g %g %g %g] readonly def\n", /* head_data.s16(36), head_data.s16(38), head_data.s16(40), head_data.s16(42)); */ head_data.s16(36) / emunits, head_data.s16(38) / emunits, head_data.s16(40) / emunits, head_data.s16(42) / emunits); fprintf(f, "/PaintType 0 def\n"); // XUID (MD5 sum of font data) { MD5_CONTEXT md5; md5_init(&md5); md5_update(&md5, (const unsigned char *) reduced_font.data(), reduced_font.length()); unsigned char result[MD5_DIGEST_SIZE + 3]; memset(result, 0, sizeof(result)); md5_final(result, &md5); fprintf(f, "/XUID [42"); for (int i = 0; i < MD5_DIGEST_SIZE; i += 3) fprintf(f, " 16#%X", result[i] + result[i+1]*256 + result[i+2]*256*256); fprintf(f, "] def\n"); } // FontInfo dictionary fprintf(f, "/FontInfo 10 dict dup begin\n"); for (const NameId *n = fontinfo_names; n->name; n++) if (String s = name.english_name(n->nameid)) { fprintf(f, "/%s (", n->name); for (const char *x = s.begin(); x < s.end(); x++) if (*x == '(' || *x == '\\' || *x == ')') fprintf(f, "\\%c", *x); else if (*x == '\n' || (*x >= ' ' && *x <= '~')) fputc(*x, f); else fprintf(f, "\\%03o", (unsigned char) *x); fprintf(f, ") readonly def\n"); } if (post.ok()) { fprintf(f, "/isFixedPitch %s def\n", (post.is_fixed_pitch() ? "true" : "false")); fprintf(f, "/ItalicAngle %g def\n", post.italic_angle()); fprintf(f, "/UnderlinePosition %g def\n", (post.underline_position() - (post.underline_thickness() / 2)) / emunits); fprintf(f, "/UnderlineThickness %g def\n", post.underline_thickness() / emunits); } fprintf(f, "end readonly def\n"); // encoding fprintf(f, "/Encoding 256 array\n0 1 255{1 index exch/.notdef put}for\n"); for (int i = 0; i < 256; i++) if (OpenType::Glyph g = cmap.map_uni(i)) fprintf(f, "dup %d /%s put\n", i, gn[g].c_str()); fprintf(f, "readonly def\n"); // print 'sfnts' array OpenType::Data sfnts = reduced_font.data_string(); fprintf(f, "/sfnts[\n"); fprint_sfnts(f, sfnts.substring(0, OpenType::Font::HEADER_SIZE + OpenType::Font::TABLE_DIR_ENTRY_SIZE * reduced_font.ntables()), false, reduced_font); for (int i = 0; i < reduced_font.ntables(); i++) { int off = OpenType::Font::HEADER_SIZE + OpenType::Font::TABLE_DIR_ENTRY_SIZE * i; uint32_t offset = sfnts.u32(off + 8); uint32_t length = (sfnts.u32(off + 12) + 3) & ~3; fprint_sfnts(f, sfnts.substring(offset, length), sfnts.u32(off) == 0x676C7966 /*glyf*/, reduced_font); } fprintf(f, "] def\n"); // print CharStrings data fprintf(f, "/CharStrings %d dict dup begin\n", ttbprog.nglyphs()); for (int i = 0; i < gn.size(); i++) fprintf(f, "/%s %d def\n", gn[i].c_str(), i); fprintf(f, "end readonly def\n"); // complete font fprintf(f, "FontName currentdict end definefont pop\n"); // fprintf(f, "/%s 100 selectfont 30 30 moveto (Hello! 9) show showpage\n", name.english_name(OpenType::Name::N_POSTSCRIPT).c_str()); if (f != stdout) fclose(f); } #if 0 static void check_md5sum() { MD5_CONTEXT md5; md5_init(&md5); md5_update(&md5, (const unsigned char *) "message digest", 14); unsigned char result[MD5_DIGEST_SIZE]; md5_final(result, &md5); assert(memcmp(result, "\xF9\x6B\x69\x7D\x7C\xB7\x93\x8D\x52\x5A\x2F\x31\xAA\xF1\x61\xD0", MD5_DIGEST_SIZE) == 0); } #endif int main(int argc, char *argv[]) { Clp_Parser *clp = Clp_NewParser(argc, (const char * const *)argv, sizeof(options) / sizeof(options[0]), options); program_name = Clp_ProgramName(clp); ErrorHandler *errh = ErrorHandler::static_initialize(new FileErrorHandler(stderr, String(program_name) + ": ")); const char *input_file = 0; const char *output_file = 0; while (1) { int opt = Clp_Next(clp); switch (opt) { case QUIET_OPT: if (clp->negated) errh = ErrorHandler::default_handler(); else errh = new SilentErrorHandler; break; case VERSION_OPT: printf("ttftotype42 (LCDF typetools) %s\n", VERSION); printf("Copyright (C) 2006-2019 Eddie Kohler\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); exit(0); break; case HELP_OPT: usage(); exit(0); break; case OUTPUT_OPT: output_file: if (output_file) usage_error(errh, "output file specified twice"); output_file = clp->vstr; break; case Clp_NotOption: if (input_file && output_file) usage_error(errh, "too many arguments"); else if (input_file) goto output_file; else input_file = clp->vstr; break; case Clp_Done: goto done; case Clp_BadOption: usage_error(errh, 0); break; default: break; } } done: do_file(input_file, output_file, errh); return (errh->nerrors() == 0 ? 0 : 1); } lcdf-typetools-2.108/ttftotype42/Makefile.in0000644000175000017500000005115013423376574015712 00000000000000# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : bin_PROGRAMS = ttftotype42$(EXEEXT) subdir = ttftotype42 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/lcdf-typetools.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/autoconf.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" PROGRAMS = $(bin_PROGRAMS) am_ttftotype42_OBJECTS = ttftotype42.$(OBJEXT) ttftotype42_OBJECTS = $(am_ttftotype42_OBJECTS) ttftotype42_DEPENDENCIES = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(ttftotype42_SOURCES) DIST_SOURCES = $(ttftotype42_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KPATHSEA_DEPEND = @KPATHSEA_DEPEND@ KPATHSEA_INCLUDES = @KPATHSEA_INCLUDES@ KPATHSEA_LIBS = @KPATHSEA_LIBS@ KPATHSEA_RULE = @KPATHSEA_RULE@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SELECTED_SUBDIRS = @SELECTED_SUBDIRS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TEMPLATE_OBJS = @TEMPLATE_OBJS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ encdir = @encdir@ exec_prefix = @exec_prefix@ glyphlistdir = @glyphlistdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign man_MANS = ttftotype42.1 ttftotype42_SOURCES = ttftotype42.cc ttftotype42_LDADD = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_CPPFLAGS = -I$(srcdir)/../include CLEANFILES = @TEMPLATE_OBJS@ EXTRA_DIST = ttftotype42.1 all: all-am .SUFFIXES: .SUFFIXES: .cc .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign ttftotype42/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign ttftotype42/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) ttftotype42$(EXEEXT): $(ttftotype42_OBJECTS) $(ttftotype42_DEPENDENCIES) $(EXTRA_ttftotype42_DEPENDENCIES) @rm -f ttftotype42$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(ttftotype42_OBJECTS) $(ttftotype42_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ttftotype42.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-man uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-binPROGRAMS install-data install-data-am \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-man1 install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-binPROGRAMS uninstall-man uninstall-man1 .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lcdf-typetools-2.108/ttftotype42/ttftotype42.10000644000175000017500000000307313423376706016135 00000000000000.ds V 2.108 .de M .BR "\\$1" "(\\$2)\\$3" .. .de Sp .if n .sp .if t .sp 0.4 .. .TH TTFTOTYPE42 1 "LCDF Typetools" "Version \*V" .SH NAME ttftotype42 \- create PostScript Type 42 wrapper of TrueType font .SH SYNOPSIS .B ttftotype42 \%[\fIinput\fR [\fIoutput\fR]] .SH DESCRIPTION .BR Ttftotype42 converts TrueType or TrueType-flavored OpenType font programs into PostScript Type 42 format, which is a wrapper for the TrueType outlines. This conversion preserves all outlines and hint information from the original TrueType font. The Type 42 wrapper uses glyph names identical to those expected by .M pdflatex 1 or .M otftotfm 1 , so encoding files suitable for TrueType fonts and .B pdflatex will also work for the Type 42 fonts and .M dvips 1 . If the file .I output is not specified output goes to the standard output. If the file .I input is not specified input comes from the standard input. ' .SH OPTIONS .PD 0 .TP 5 .BI \-o " file\fR, " \-\-output " file" Write output font to .IR file instead of the standard output. ' .Sp .TP 5 .BR \-q ", " \-\-quiet Do not generate any error messages. ' .Sp .TP 5 .BR \-h ", " \-\-help Print usage information and exit. ' .Sp .TP 5 .BR \-v ", " \-\-version Print the version number and some short non-warranty information and exit. .PD ' .SH "SEE ALSO" .LP .M cfftot1 1 , .M otftotfm 1 , .M pdftex 1 , .M dvips 1 .LP Adobe Technical Note #5012, .IR "The Type 42 Font Format Specification" .LP .IR "OpenType Specification" , Version 1.4 ' .SH AUTHOR Eddie Kohler (ekohler@gmail.com) .PP The latest version is available from: .br http://www.lcdf.org/type/ lcdf-typetools-2.108/ttftotype42/Makefile.am0000664000175000017500000000052012732752520015665 00000000000000## Process this file with automake to produce Makefile.in AUTOMAKE_OPTIONS = foreign bin_PROGRAMS = ttftotype42 man_MANS = ttftotype42.1 ttftotype42_SOURCES = ttftotype42.cc ttftotype42_LDADD = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_CPPFLAGS = -I$(srcdir)/../include CLEANFILES = @TEMPLATE_OBJS@ EXTRA_DIST = ttftotype42.1 lcdf-typetools-2.108/glyphtounicode.tex0000644000175000017500000064725313423377073015226 00000000000000% lcdf-typetools glyphtounicode.tex, Version 2.95 % Contents: Glyph mapping information for pdftex, used for PDF searching % Generated from: % - glyphlist.txt, Version 2.0 % - texglyphlist.txt, Version 2.95 % - texglyphlist-g2u.txt, Version 2.95 \pdfglyphtounicode{A}{0041} \pdfglyphtounicode{AE}{00C6} \pdfglyphtounicode{AEacute}{01FC} \pdfglyphtounicode{AEmacron}{01E2} \pdfglyphtounicode{AEsmall}{00E6} \pdfglyphtounicode{Aacute}{00C1} \pdfglyphtounicode{Aacutesmall}{00E1} \pdfglyphtounicode{Abreve}{0102} \pdfglyphtounicode{Abreveacute}{1EAE} \pdfglyphtounicode{Abrevecyrillic}{04D0} \pdfglyphtounicode{Abrevedotbelow}{1EB6} \pdfglyphtounicode{Abrevegrave}{1EB0} \pdfglyphtounicode{Abrevehookabove}{1EB2} \pdfglyphtounicode{Abrevetilde}{1EB4} \pdfglyphtounicode{Acaron}{01CD} \pdfglyphtounicode{Acircle}{24B6} \pdfglyphtounicode{Acircumflex}{00C2} \pdfglyphtounicode{Acircumflexacute}{1EA4} \pdfglyphtounicode{Acircumflexdotbelow}{1EAC} \pdfglyphtounicode{Acircumflexgrave}{1EA6} \pdfglyphtounicode{Acircumflexhookabove}{1EA8} \pdfglyphtounicode{Acircumflexsmall}{00E2} \pdfglyphtounicode{Acircumflextilde}{1EAA} \pdfglyphtounicode{Acute}{00B4} \pdfglyphtounicode{Acutesmall}{00B4} \pdfglyphtounicode{Acyrillic}{0410} \pdfglyphtounicode{Adblgrave}{0200} \pdfglyphtounicode{Adieresis}{00C4} \pdfglyphtounicode{Adieresiscyrillic}{04D2} \pdfglyphtounicode{Adieresismacron}{01DE} \pdfglyphtounicode{Adieresissmall}{00E4} \pdfglyphtounicode{Adotbelow}{1EA0} \pdfglyphtounicode{Adotmacron}{01E0} \pdfglyphtounicode{Agrave}{00C0} \pdfglyphtounicode{Agravesmall}{00E0} \pdfglyphtounicode{Ahookabove}{1EA2} \pdfglyphtounicode{Aiecyrillic}{04D4} \pdfglyphtounicode{Ainvertedbreve}{0202} \pdfglyphtounicode{Alpha}{0391} \pdfglyphtounicode{Alphatonos}{0386} \pdfglyphtounicode{Amacron}{0100} \pdfglyphtounicode{Amonospace}{FF21} \pdfglyphtounicode{Aogonek}{0104} \pdfglyphtounicode{Aring}{00C5} \pdfglyphtounicode{Aringacute}{01FA} \pdfglyphtounicode{Aringbelow}{1E00} \pdfglyphtounicode{Aringsmall}{00E5} \pdfglyphtounicode{Asmall}{0061} \pdfglyphtounicode{Atilde}{00C3} \pdfglyphtounicode{Atildesmall}{00E3} \pdfglyphtounicode{Aybarmenian}{0531} \pdfglyphtounicode{B}{0042} \pdfglyphtounicode{Bcircle}{24B7} \pdfglyphtounicode{Bdotaccent}{1E02} \pdfglyphtounicode{Bdotbelow}{1E04} \pdfglyphtounicode{Becyrillic}{0411} \pdfglyphtounicode{Benarmenian}{0532} \pdfglyphtounicode{Beta}{0392} \pdfglyphtounicode{Bhook}{0181} \pdfglyphtounicode{Blinebelow}{1E06} \pdfglyphtounicode{Bmonospace}{FF22} \pdfglyphtounicode{Brevesmall}{02D8} \pdfglyphtounicode{Bsmall}{0062} \pdfglyphtounicode{Btopbar}{0182} \pdfglyphtounicode{C}{0043} \pdfglyphtounicode{Caarmenian}{053E} \pdfglyphtounicode{Cacute}{0106} \pdfglyphtounicode{Caron}{02C7} \pdfglyphtounicode{Caronsmall}{02C7} \pdfglyphtounicode{Ccaron}{010C} \pdfglyphtounicode{Ccedilla}{00C7} \pdfglyphtounicode{Ccedillaacute}{1E08} \pdfglyphtounicode{Ccedillasmall}{00E7} \pdfglyphtounicode{Ccircle}{24B8} \pdfglyphtounicode{Ccircumflex}{0108} \pdfglyphtounicode{Cdot}{010A} \pdfglyphtounicode{Cdotaccent}{010A} \pdfglyphtounicode{Cedillasmall}{00B8} \pdfglyphtounicode{Chaarmenian}{0549} \pdfglyphtounicode{Cheabkhasiancyrillic}{04BC} \pdfglyphtounicode{Checyrillic}{0427} \pdfglyphtounicode{Chedescenderabkhasiancyrillic}{04BE} \pdfglyphtounicode{Chedescendercyrillic}{04B6} \pdfglyphtounicode{Chedieresiscyrillic}{04F4} \pdfglyphtounicode{Cheharmenian}{0543} \pdfglyphtounicode{Chekhakassiancyrillic}{04CB} \pdfglyphtounicode{Cheverticalstrokecyrillic}{04B8} \pdfglyphtounicode{Chi}{03A7} \pdfglyphtounicode{Chook}{0187} \pdfglyphtounicode{Circumflexsmall}{02C6} \pdfglyphtounicode{Cmonospace}{FF23} \pdfglyphtounicode{Coarmenian}{0551} \pdfglyphtounicode{Csmall}{0063} \pdfglyphtounicode{D}{0044} \pdfglyphtounicode{DZ}{01F1} \pdfglyphtounicode{DZcaron}{01C4} \pdfglyphtounicode{Daarmenian}{0534} \pdfglyphtounicode{Dafrican}{0189} \pdfglyphtounicode{Dbar}{0110} \pdfglyphtounicode{Dcaron}{010E} \pdfglyphtounicode{Dcedilla}{1E10} \pdfglyphtounicode{Dcircle}{24B9} \pdfglyphtounicode{Dcircumflexbelow}{1E12} \pdfglyphtounicode{Dcroat}{0110} \pdfglyphtounicode{Ddotaccent}{1E0A} \pdfglyphtounicode{Ddotbelow}{1E0C} \pdfglyphtounicode{Decyrillic}{0414} \pdfglyphtounicode{Deicoptic}{03EE} \pdfglyphtounicode{Delta}{2206} \pdfglyphtounicode{Deltagreek}{0394} \pdfglyphtounicode{Dhook}{018A} \pdfglyphtounicode{Dieresis}{00A8} \pdfglyphtounicode{DieresisAcute}{F6CC} \pdfglyphtounicode{DieresisGrave}{F6CD} \pdfglyphtounicode{Dieresissmall}{00A8} \pdfglyphtounicode{Digamma}{D875 DFCB} \pdfglyphtounicode{Digammagreek}{03DC} \pdfglyphtounicode{Djecyrillic}{0402} \pdfglyphtounicode{Dlinebelow}{1E0E} \pdfglyphtounicode{Dmonospace}{FF24} \pdfglyphtounicode{Dotaccentsmall}{02D9} \pdfglyphtounicode{Dslash}{0110} \pdfglyphtounicode{Dsmall}{0064} \pdfglyphtounicode{Dtopbar}{018B} \pdfglyphtounicode{Dz}{01F2} \pdfglyphtounicode{Dzcaron}{01C5} \pdfglyphtounicode{Dzeabkhasiancyrillic}{04E0} \pdfglyphtounicode{Dzecyrillic}{0405} \pdfglyphtounicode{Dzhecyrillic}{040F} \pdfglyphtounicode{E}{0045} \pdfglyphtounicode{Eacute}{00C9} \pdfglyphtounicode{Eacutesmall}{00E9} \pdfglyphtounicode{Ebreve}{0114} \pdfglyphtounicode{Ecaron}{011A} \pdfglyphtounicode{Ecedillabreve}{1E1C} \pdfglyphtounicode{Echarmenian}{0535} \pdfglyphtounicode{Ecircle}{24BA} \pdfglyphtounicode{Ecircumflex}{00CA} \pdfglyphtounicode{Ecircumflexacute}{1EBE} \pdfglyphtounicode{Ecircumflexbelow}{1E18} \pdfglyphtounicode{Ecircumflexdotbelow}{1EC6} \pdfglyphtounicode{Ecircumflexgrave}{1EC0} \pdfglyphtounicode{Ecircumflexhookabove}{1EC2} \pdfglyphtounicode{Ecircumflexsmall}{00EA} \pdfglyphtounicode{Ecircumflextilde}{1EC4} \pdfglyphtounicode{Ecyrillic}{0404} \pdfglyphtounicode{Edblgrave}{0204} \pdfglyphtounicode{Edieresis}{00CB} \pdfglyphtounicode{Edieresissmall}{00EB} \pdfglyphtounicode{Edot}{0116} \pdfglyphtounicode{Edotaccent}{0116} \pdfglyphtounicode{Edotbelow}{1EB8} \pdfglyphtounicode{Efcyrillic}{0424} \pdfglyphtounicode{Egrave}{00C8} \pdfglyphtounicode{Egravesmall}{00E8} \pdfglyphtounicode{Eharmenian}{0537} \pdfglyphtounicode{Ehookabove}{1EBA} \pdfglyphtounicode{Eightroman}{2167} \pdfglyphtounicode{Einvertedbreve}{0206} \pdfglyphtounicode{Eiotifiedcyrillic}{0464} \pdfglyphtounicode{Elcyrillic}{041B} \pdfglyphtounicode{Elevenroman}{216A} \pdfglyphtounicode{Emacron}{0112} \pdfglyphtounicode{Emacronacute}{1E16} \pdfglyphtounicode{Emacrongrave}{1E14} \pdfglyphtounicode{Emcyrillic}{041C} \pdfglyphtounicode{Emonospace}{FF25} \pdfglyphtounicode{Encyrillic}{041D} \pdfglyphtounicode{Endescendercyrillic}{04A2} \pdfglyphtounicode{Eng}{014A} \pdfglyphtounicode{Enghecyrillic}{04A4} \pdfglyphtounicode{Enhookcyrillic}{04C7} \pdfglyphtounicode{Eogonek}{0118} \pdfglyphtounicode{Eopen}{0190} \pdfglyphtounicode{Epsilon}{0395} \pdfglyphtounicode{Epsilontonos}{0388} \pdfglyphtounicode{Ercyrillic}{0420} \pdfglyphtounicode{Ereversed}{018E} \pdfglyphtounicode{Ereversedcyrillic}{042D} \pdfglyphtounicode{Escyrillic}{0421} \pdfglyphtounicode{Esdescendercyrillic}{04AA} \pdfglyphtounicode{Esh}{01A9} \pdfglyphtounicode{Esmall}{0065} \pdfglyphtounicode{Eta}{0397} \pdfglyphtounicode{Etarmenian}{0538} \pdfglyphtounicode{Etatonos}{0389} \pdfglyphtounicode{Eth}{00D0} \pdfglyphtounicode{Ethsmall}{00F0} \pdfglyphtounicode{Etilde}{1EBC} \pdfglyphtounicode{Etildebelow}{1E1A} \pdfglyphtounicode{Euro}{20AC} \pdfglyphtounicode{Ezh}{01B7} \pdfglyphtounicode{Ezhcaron}{01EE} \pdfglyphtounicode{Ezhreversed}{01B8} \pdfglyphtounicode{F}{0046} \pdfglyphtounicode{FFIsmall}{0066 0066 0069} \pdfglyphtounicode{FFLsmall}{0066 0066 006C} \pdfglyphtounicode{FFsmall}{0066 0066} \pdfglyphtounicode{FIsmall}{0066 0069} \pdfglyphtounicode{FLsmall}{0066 006C} \pdfglyphtounicode{Fcircle}{24BB} \pdfglyphtounicode{Fdotaccent}{1E1E} \pdfglyphtounicode{Feharmenian}{0556} \pdfglyphtounicode{Feicoptic}{03E4} \pdfglyphtounicode{Fhook}{0191} \pdfglyphtounicode{Finv}{2132} \pdfglyphtounicode{Fitacyrillic}{0472} \pdfglyphtounicode{Fiveroman}{2164} \pdfglyphtounicode{Fmonospace}{FF26} \pdfglyphtounicode{Fourroman}{2163} \pdfglyphtounicode{Fsmall}{0066} \pdfglyphtounicode{G}{0047} \pdfglyphtounicode{GBsquare}{3387} \pdfglyphtounicode{Gacute}{01F4} \pdfglyphtounicode{Gamma}{0393} \pdfglyphtounicode{Gammaafrican}{0194} \pdfglyphtounicode{Gangiacoptic}{03EA} \pdfglyphtounicode{Gbreve}{011E} \pdfglyphtounicode{Gcaron}{01E6} \pdfglyphtounicode{Gcedilla}{0122} \pdfglyphtounicode{Gcircle}{24BC} \pdfglyphtounicode{Gcircumflex}{011C} \pdfglyphtounicode{Gcommaaccent}{0122} \pdfglyphtounicode{Gdot}{0120} \pdfglyphtounicode{Gdotaccent}{0120} \pdfglyphtounicode{Gecyrillic}{0413} \pdfglyphtounicode{Germandbls}{0053 0053} \pdfglyphtounicode{Germandblssmall}{0073 0073} \pdfglyphtounicode{Ghadarmenian}{0542} \pdfglyphtounicode{Ghemiddlehookcyrillic}{0494} \pdfglyphtounicode{Ghestrokecyrillic}{0492} \pdfglyphtounicode{Gheupturncyrillic}{0490} \pdfglyphtounicode{Ghook}{0193} \pdfglyphtounicode{Gimarmenian}{0533} \pdfglyphtounicode{Gjecyrillic}{0403} \pdfglyphtounicode{Gmacron}{1E20} \pdfglyphtounicode{Gmir}{2141} \pdfglyphtounicode{Gmonospace}{FF27} \pdfglyphtounicode{Grave}{0060} \pdfglyphtounicode{Gravesmall}{0060} \pdfglyphtounicode{Gsmall}{0067} \pdfglyphtounicode{Gsmallhook}{029B} \pdfglyphtounicode{Gstroke}{01E4} \pdfglyphtounicode{H}{0048} \pdfglyphtounicode{H18533}{25CF} \pdfglyphtounicode{H18543}{25AA} \pdfglyphtounicode{H18551}{25AB} \pdfglyphtounicode{H22073}{25A1} \pdfglyphtounicode{HPsquare}{33CB} \pdfglyphtounicode{Haabkhasiancyrillic}{04A8} \pdfglyphtounicode{Hadescendercyrillic}{04B2} \pdfglyphtounicode{Hardsigncyrillic}{042A} \pdfglyphtounicode{Hbar}{0126} \pdfglyphtounicode{Hbrevebelow}{1E2A} \pdfglyphtounicode{Hcedilla}{1E28} \pdfglyphtounicode{Hcircle}{24BD} \pdfglyphtounicode{Hcircumflex}{0124} \pdfglyphtounicode{Hdieresis}{1E26} \pdfglyphtounicode{Hdotaccent}{1E22} \pdfglyphtounicode{Hdotbelow}{1E24} \pdfglyphtounicode{Hmonospace}{FF28} \pdfglyphtounicode{Hoarmenian}{0540} \pdfglyphtounicode{Horicoptic}{03E8} \pdfglyphtounicode{Hsmall}{0068} \pdfglyphtounicode{Hungarumlaut}{02DD} \pdfglyphtounicode{Hungarumlautsmall}{02DD} \pdfglyphtounicode{Hzsquare}{3390} \pdfglyphtounicode{I}{0049} \pdfglyphtounicode{IAcyrillic}{042F} \pdfglyphtounicode{IJ}{0132} \pdfglyphtounicode{IUcyrillic}{042E} \pdfglyphtounicode{Iacute}{00CD} \pdfglyphtounicode{Iacutesmall}{00ED} \pdfglyphtounicode{Ibreve}{012C} \pdfglyphtounicode{Icaron}{01CF} \pdfglyphtounicode{Icircle}{24BE} \pdfglyphtounicode{Icircumflex}{00CE} \pdfglyphtounicode{Icircumflexsmall}{00EE} \pdfglyphtounicode{Icyrillic}{0406} \pdfglyphtounicode{Idblgrave}{0208} \pdfglyphtounicode{Idieresis}{00CF} \pdfglyphtounicode{Idieresisacute}{1E2E} \pdfglyphtounicode{Idieresiscyrillic}{04E4} \pdfglyphtounicode{Idieresissmall}{00EF} \pdfglyphtounicode{Idot}{0130} \pdfglyphtounicode{Idotaccent}{0130} \pdfglyphtounicode{Idotbelow}{1ECA} \pdfglyphtounicode{Iebrevecyrillic}{04D6} \pdfglyphtounicode{Iecyrillic}{0415} \pdfglyphtounicode{Ifractur}{2111} \pdfglyphtounicode{Ifraktur}{2111} \pdfglyphtounicode{Igrave}{00CC} \pdfglyphtounicode{Igravesmall}{00EC} \pdfglyphtounicode{Ihookabove}{1EC8} \pdfglyphtounicode{Iicyrillic}{0418} \pdfglyphtounicode{Iinvertedbreve}{020A} \pdfglyphtounicode{Iishortcyrillic}{0419} \pdfglyphtounicode{Imacron}{012A} \pdfglyphtounicode{Imacroncyrillic}{04E2} \pdfglyphtounicode{Imonospace}{FF29} \pdfglyphtounicode{Iniarmenian}{053B} \pdfglyphtounicode{Iocyrillic}{0401} \pdfglyphtounicode{Iogonek}{012E} \pdfglyphtounicode{Iota}{0399} \pdfglyphtounicode{Iotaafrican}{0196} \pdfglyphtounicode{Iotadieresis}{03AA} \pdfglyphtounicode{Iotatonos}{038A} \pdfglyphtounicode{Ismall}{0069} \pdfglyphtounicode{Istroke}{0197} \pdfglyphtounicode{Itilde}{0128} \pdfglyphtounicode{Itildebelow}{1E2C} \pdfglyphtounicode{Izhitsacyrillic}{0474} \pdfglyphtounicode{Izhitsadblgravecyrillic}{0476} \pdfglyphtounicode{J}{004A} \pdfglyphtounicode{Jaarmenian}{0541} \pdfglyphtounicode{Jcircle}{24BF} \pdfglyphtounicode{Jcircumflex}{0134} \pdfglyphtounicode{Jecyrillic}{0408} \pdfglyphtounicode{Jheharmenian}{054B} \pdfglyphtounicode{Jmonospace}{FF2A} \pdfglyphtounicode{Jsmall}{006A} \pdfglyphtounicode{K}{004B} \pdfglyphtounicode{KBsquare}{3385} \pdfglyphtounicode{KKsquare}{33CD} \pdfglyphtounicode{Kabashkircyrillic}{04A0} \pdfglyphtounicode{Kacute}{1E30} \pdfglyphtounicode{Kacyrillic}{041A} \pdfglyphtounicode{Kadescendercyrillic}{049A} \pdfglyphtounicode{Kahookcyrillic}{04C3} \pdfglyphtounicode{Kappa}{039A} \pdfglyphtounicode{Kastrokecyrillic}{049E} \pdfglyphtounicode{Kaverticalstrokecyrillic}{049C} \pdfglyphtounicode{Kcaron}{01E8} \pdfglyphtounicode{Kcedilla}{0136} \pdfglyphtounicode{Kcircle}{24C0} \pdfglyphtounicode{Kcommaaccent}{0136} \pdfglyphtounicode{Kdotbelow}{1E32} \pdfglyphtounicode{Keharmenian}{0554} \pdfglyphtounicode{Kenarmenian}{053F} \pdfglyphtounicode{Khacyrillic}{0425} \pdfglyphtounicode{Kheicoptic}{03E6} \pdfglyphtounicode{Khook}{0198} \pdfglyphtounicode{Kjecyrillic}{040C} \pdfglyphtounicode{Klinebelow}{1E34} \pdfglyphtounicode{Kmonospace}{FF2B} \pdfglyphtounicode{Koppacyrillic}{0480} \pdfglyphtounicode{Koppagreek}{03DE} \pdfglyphtounicode{Ksicyrillic}{046E} \pdfglyphtounicode{Ksmall}{006B} \pdfglyphtounicode{L}{004C} \pdfglyphtounicode{LJ}{01C7} \pdfglyphtounicode{LL}{004C 004C} \pdfglyphtounicode{Lacute}{0139} \pdfglyphtounicode{Lambda}{039B} \pdfglyphtounicode{Lcaron}{013D} \pdfglyphtounicode{Lcedilla}{013B} \pdfglyphtounicode{Lcircle}{24C1} \pdfglyphtounicode{Lcircumflexbelow}{1E3C} \pdfglyphtounicode{Lcommaaccent}{013B} \pdfglyphtounicode{Ldot}{013F} \pdfglyphtounicode{Ldotaccent}{013F} \pdfglyphtounicode{Ldotbelow}{1E36} \pdfglyphtounicode{Ldotbelowmacron}{1E38} \pdfglyphtounicode{Liwnarmenian}{053C} \pdfglyphtounicode{Lj}{01C8} \pdfglyphtounicode{Ljecyrillic}{0409} \pdfglyphtounicode{Llinebelow}{1E3A} \pdfglyphtounicode{Lmonospace}{FF2C} \pdfglyphtounicode{Lslash}{0141} \pdfglyphtounicode{Lslashsmall}{0142} \pdfglyphtounicode{Lsmall}{006C} \pdfglyphtounicode{M}{004D} \pdfglyphtounicode{MBsquare}{3386} \pdfglyphtounicode{Macron}{00AF} \pdfglyphtounicode{Macronsmall}{00AF} \pdfglyphtounicode{Macute}{1E3E} \pdfglyphtounicode{Mcircle}{24C2} \pdfglyphtounicode{Mdotaccent}{1E40} \pdfglyphtounicode{Mdotbelow}{1E42} \pdfglyphtounicode{Menarmenian}{0544} \pdfglyphtounicode{Mmonospace}{FF2D} \pdfglyphtounicode{Msmall}{006D} \pdfglyphtounicode{Mturned}{019C} \pdfglyphtounicode{Mu}{039C} \pdfglyphtounicode{N}{004E} \pdfglyphtounicode{NJ}{01CA} \pdfglyphtounicode{Nacute}{0143} \pdfglyphtounicode{Ncaron}{0147} \pdfglyphtounicode{Ncedilla}{0145} \pdfglyphtounicode{Ncircle}{24C3} \pdfglyphtounicode{Ncircumflexbelow}{1E4A} \pdfglyphtounicode{Ncommaaccent}{0145} \pdfglyphtounicode{Ndotaccent}{1E44} \pdfglyphtounicode{Ndotbelow}{1E46} \pdfglyphtounicode{Ng}{014A} \pdfglyphtounicode{Nhookleft}{019D} \pdfglyphtounicode{Nineroman}{2168} \pdfglyphtounicode{Nj}{01CB} \pdfglyphtounicode{Njecyrillic}{040A} \pdfglyphtounicode{Nlinebelow}{1E48} \pdfglyphtounicode{Nmonospace}{FF2E} \pdfglyphtounicode{Nowarmenian}{0546} \pdfglyphtounicode{Nsmall}{006E} \pdfglyphtounicode{Ntilde}{00D1} \pdfglyphtounicode{Ntildesmall}{00F1} \pdfglyphtounicode{Nu}{039D} \pdfglyphtounicode{O}{004F} \pdfglyphtounicode{OE}{0152} \pdfglyphtounicode{OEsmall}{0153} \pdfglyphtounicode{Oacute}{00D3} \pdfglyphtounicode{Oacutesmall}{00F3} \pdfglyphtounicode{Obarredcyrillic}{04E8} \pdfglyphtounicode{Obarreddieresiscyrillic}{04EA} \pdfglyphtounicode{Obreve}{014E} \pdfglyphtounicode{Ocaron}{01D1} \pdfglyphtounicode{Ocenteredtilde}{019F} \pdfglyphtounicode{Ocircle}{24C4} \pdfglyphtounicode{Ocircumflex}{00D4} \pdfglyphtounicode{Ocircumflexacute}{1ED0} \pdfglyphtounicode{Ocircumflexdotbelow}{1ED8} \pdfglyphtounicode{Ocircumflexgrave}{1ED2} \pdfglyphtounicode{Ocircumflexhookabove}{1ED4} \pdfglyphtounicode{Ocircumflexsmall}{00F4} \pdfglyphtounicode{Ocircumflextilde}{1ED6} \pdfglyphtounicode{Ocyrillic}{041E} \pdfglyphtounicode{Odblacute}{0150} \pdfglyphtounicode{Odblgrave}{020C} \pdfglyphtounicode{Odieresis}{00D6} \pdfglyphtounicode{Odieresiscyrillic}{04E6} \pdfglyphtounicode{Odieresissmall}{00F6} \pdfglyphtounicode{Odotbelow}{1ECC} \pdfglyphtounicode{Ogoneksmall}{02DB} \pdfglyphtounicode{Ograve}{00D2} \pdfglyphtounicode{Ogravesmall}{00F2} \pdfglyphtounicode{Oharmenian}{0555} \pdfglyphtounicode{Ohm}{2126} \pdfglyphtounicode{Ohookabove}{1ECE} \pdfglyphtounicode{Ohorn}{01A0} \pdfglyphtounicode{Ohornacute}{1EDA} \pdfglyphtounicode{Ohorndotbelow}{1EE2} \pdfglyphtounicode{Ohorngrave}{1EDC} \pdfglyphtounicode{Ohornhookabove}{1EDE} \pdfglyphtounicode{Ohorntilde}{1EE0} \pdfglyphtounicode{Ohungarumlaut}{0150} \pdfglyphtounicode{Oi}{01A2} \pdfglyphtounicode{Oinvertedbreve}{020E} \pdfglyphtounicode{Omacron}{014C} \pdfglyphtounicode{Omacronacute}{1E52} \pdfglyphtounicode{Omacrongrave}{1E50} \pdfglyphtounicode{Omega}{2126} \pdfglyphtounicode{Omegacyrillic}{0460} \pdfglyphtounicode{Omegagreek}{03A9} \pdfglyphtounicode{Omegainv}{2127} \pdfglyphtounicode{Omegaroundcyrillic}{047A} \pdfglyphtounicode{Omegatitlocyrillic}{047C} \pdfglyphtounicode{Omegatonos}{038F} \pdfglyphtounicode{Omicron}{039F} \pdfglyphtounicode{Omicrontonos}{038C} \pdfglyphtounicode{Omonospace}{FF2F} \pdfglyphtounicode{Oneroman}{2160} \pdfglyphtounicode{Oogonek}{01EA} \pdfglyphtounicode{Oogonekmacron}{01EC} \pdfglyphtounicode{Oopen}{0186} \pdfglyphtounicode{Oslash}{00D8} \pdfglyphtounicode{Oslashacute}{01FE} \pdfglyphtounicode{Oslashsmall}{00F8} \pdfglyphtounicode{Osmall}{006F} \pdfglyphtounicode{Ostrokeacute}{01FE} \pdfglyphtounicode{Otcyrillic}{047E} \pdfglyphtounicode{Otilde}{00D5} \pdfglyphtounicode{Otildeacute}{1E4C} \pdfglyphtounicode{Otildedieresis}{1E4E} \pdfglyphtounicode{Otildesmall}{00F5} \pdfglyphtounicode{P}{0050} \pdfglyphtounicode{Pacute}{1E54} \pdfglyphtounicode{Pcircle}{24C5} \pdfglyphtounicode{Pdotaccent}{1E56} \pdfglyphtounicode{Pecyrillic}{041F} \pdfglyphtounicode{Peharmenian}{054A} \pdfglyphtounicode{Pemiddlehookcyrillic}{04A6} \pdfglyphtounicode{Phi}{03A6} \pdfglyphtounicode{Phook}{01A4} \pdfglyphtounicode{Pi}{03A0} \pdfglyphtounicode{Piwrarmenian}{0553} \pdfglyphtounicode{Pmonospace}{FF30} \pdfglyphtounicode{Psi}{03A8} \pdfglyphtounicode{Psicyrillic}{0470} \pdfglyphtounicode{Psmall}{0070} \pdfglyphtounicode{Q}{0051} \pdfglyphtounicode{Qcircle}{24C6} \pdfglyphtounicode{Qmonospace}{FF31} \pdfglyphtounicode{Qsmall}{0071} \pdfglyphtounicode{R}{0052} \pdfglyphtounicode{Raarmenian}{054C} \pdfglyphtounicode{Racute}{0154} \pdfglyphtounicode{Rcaron}{0158} \pdfglyphtounicode{Rcedilla}{0156} \pdfglyphtounicode{Rcircle}{24C7} \pdfglyphtounicode{Rcommaaccent}{0156} \pdfglyphtounicode{Rdblgrave}{0210} \pdfglyphtounicode{Rdotaccent}{1E58} \pdfglyphtounicode{Rdotbelow}{1E5A} \pdfglyphtounicode{Rdotbelowmacron}{1E5C} \pdfglyphtounicode{Reharmenian}{0550} \pdfglyphtounicode{Rfractur}{211C} \pdfglyphtounicode{Rfraktur}{211C} \pdfglyphtounicode{Rho}{03A1} \pdfglyphtounicode{Ringsmall}{02DA} \pdfglyphtounicode{Rinvertedbreve}{0212} \pdfglyphtounicode{Rlinebelow}{1E5E} \pdfglyphtounicode{Rmonospace}{FF32} \pdfglyphtounicode{Rsmall}{0072} \pdfglyphtounicode{Rsmallinverted}{0281} \pdfglyphtounicode{Rsmallinvertedsuperior}{02B6} \pdfglyphtounicode{S}{0053} \pdfglyphtounicode{SF010000}{250C} \pdfglyphtounicode{SF020000}{2514} \pdfglyphtounicode{SF030000}{2510} \pdfglyphtounicode{SF040000}{2518} \pdfglyphtounicode{SF050000}{253C} \pdfglyphtounicode{SF060000}{252C} \pdfglyphtounicode{SF070000}{2534} \pdfglyphtounicode{SF080000}{251C} \pdfglyphtounicode{SF090000}{2524} \pdfglyphtounicode{SF100000}{2500} \pdfglyphtounicode{SF110000}{2502} \pdfglyphtounicode{SF190000}{2561} \pdfglyphtounicode{SF200000}{2562} \pdfglyphtounicode{SF210000}{2556} \pdfglyphtounicode{SF220000}{2555} \pdfglyphtounicode{SF230000}{2563} \pdfglyphtounicode{SF240000}{2551} \pdfglyphtounicode{SF250000}{2557} \pdfglyphtounicode{SF260000}{255D} \pdfglyphtounicode{SF270000}{255C} \pdfglyphtounicode{SF280000}{255B} \pdfglyphtounicode{SF360000}{255E} \pdfglyphtounicode{SF370000}{255F} \pdfglyphtounicode{SF380000}{255A} \pdfglyphtounicode{SF390000}{2554} \pdfglyphtounicode{SF400000}{2569} \pdfglyphtounicode{SF410000}{2566} \pdfglyphtounicode{SF420000}{2560} \pdfglyphtounicode{SF430000}{2550} \pdfglyphtounicode{SF440000}{256C} \pdfglyphtounicode{SF450000}{2567} \pdfglyphtounicode{SF460000}{2568} \pdfglyphtounicode{SF470000}{2564} \pdfglyphtounicode{SF480000}{2565} \pdfglyphtounicode{SF490000}{2559} \pdfglyphtounicode{SF500000}{2558} \pdfglyphtounicode{SF510000}{2552} \pdfglyphtounicode{SF520000}{2553} \pdfglyphtounicode{SF530000}{256B} \pdfglyphtounicode{SF540000}{256A} \pdfglyphtounicode{SS}{0053 0053} \pdfglyphtounicode{SSsmall}{0073 0073} \pdfglyphtounicode{Sacute}{015A} \pdfglyphtounicode{Sacutedotaccent}{1E64} \pdfglyphtounicode{Sampigreek}{03E0} \pdfglyphtounicode{Scaron}{0160} \pdfglyphtounicode{Scarondotaccent}{1E66} \pdfglyphtounicode{Scaronsmall}{0161} \pdfglyphtounicode{Scedilla}{015E} \pdfglyphtounicode{Schwa}{018F} \pdfglyphtounicode{Schwacyrillic}{04D8} \pdfglyphtounicode{Schwadieresiscyrillic}{04DA} \pdfglyphtounicode{Scircle}{24C8} \pdfglyphtounicode{Scircumflex}{015C} \pdfglyphtounicode{Scommaaccent}{0218} \pdfglyphtounicode{Sdotaccent}{1E60} \pdfglyphtounicode{Sdotbelow}{1E62} \pdfglyphtounicode{Sdotbelowdotaccent}{1E68} \pdfglyphtounicode{Seharmenian}{054D} \pdfglyphtounicode{Sevenroman}{2166} \pdfglyphtounicode{Shaarmenian}{0547} \pdfglyphtounicode{Shacyrillic}{0428} \pdfglyphtounicode{Shchacyrillic}{0429} \pdfglyphtounicode{Sheicoptic}{03E2} \pdfglyphtounicode{Shhacyrillic}{04BA} \pdfglyphtounicode{Shimacoptic}{03EC} \pdfglyphtounicode{Sigma}{03A3} \pdfglyphtounicode{Sixroman}{2165} \pdfglyphtounicode{Smonospace}{FF33} \pdfglyphtounicode{Softsigncyrillic}{042C} \pdfglyphtounicode{Ssmall}{0073} \pdfglyphtounicode{Stigmagreek}{03DA} \pdfglyphtounicode{T}{0054} \pdfglyphtounicode{Tau}{03A4} \pdfglyphtounicode{Tbar}{0166} \pdfglyphtounicode{Tcaron}{0164} \pdfglyphtounicode{Tcedilla}{0162} \pdfglyphtounicode{Tcircle}{24C9} \pdfglyphtounicode{Tcircumflexbelow}{1E70} \pdfglyphtounicode{Tcommaaccent}{0162} \pdfglyphtounicode{Tdotaccent}{1E6A} \pdfglyphtounicode{Tdotbelow}{1E6C} \pdfglyphtounicode{Tecyrillic}{0422} \pdfglyphtounicode{Tedescendercyrillic}{04AC} \pdfglyphtounicode{Tenroman}{2169} \pdfglyphtounicode{Tetsecyrillic}{04B4} \pdfglyphtounicode{Theta}{0398} \pdfglyphtounicode{Thook}{01AC} \pdfglyphtounicode{Thorn}{00DE} \pdfglyphtounicode{Thornsmall}{00FE} \pdfglyphtounicode{Threeroman}{2162} \pdfglyphtounicode{Tildesmall}{02DC} \pdfglyphtounicode{Tiwnarmenian}{054F} \pdfglyphtounicode{Tlinebelow}{1E6E} \pdfglyphtounicode{Tmonospace}{FF34} \pdfglyphtounicode{Toarmenian}{0539} \pdfglyphtounicode{Tonefive}{01BC} \pdfglyphtounicode{Tonesix}{0184} \pdfglyphtounicode{Tonetwo}{01A7} \pdfglyphtounicode{Tretroflexhook}{01AE} \pdfglyphtounicode{Tsecyrillic}{0426} \pdfglyphtounicode{Tshecyrillic}{040B} \pdfglyphtounicode{Tsmall}{0074} \pdfglyphtounicode{Twelveroman}{216B} \pdfglyphtounicode{Tworoman}{2161} \pdfglyphtounicode{U}{0055} \pdfglyphtounicode{Uacute}{00DA} \pdfglyphtounicode{Uacutesmall}{00FA} \pdfglyphtounicode{Ubreve}{016C} \pdfglyphtounicode{Ucaron}{01D3} \pdfglyphtounicode{Ucircle}{24CA} \pdfglyphtounicode{Ucircumflex}{00DB} \pdfglyphtounicode{Ucircumflexbelow}{1E76} \pdfglyphtounicode{Ucircumflexsmall}{00FB} \pdfglyphtounicode{Ucyrillic}{0423} \pdfglyphtounicode{Udblacute}{0170} \pdfglyphtounicode{Udblgrave}{0214} \pdfglyphtounicode{Udieresis}{00DC} \pdfglyphtounicode{Udieresisacute}{01D7} \pdfglyphtounicode{Udieresisbelow}{1E72} \pdfglyphtounicode{Udieresiscaron}{01D9} \pdfglyphtounicode{Udieresiscyrillic}{04F0} \pdfglyphtounicode{Udieresisgrave}{01DB} \pdfglyphtounicode{Udieresismacron}{01D5} \pdfglyphtounicode{Udieresissmall}{00FC} \pdfglyphtounicode{Udotbelow}{1EE4} \pdfglyphtounicode{Ugrave}{00D9} \pdfglyphtounicode{Ugravesmall}{00F9} \pdfglyphtounicode{Uhookabove}{1EE6} \pdfglyphtounicode{Uhorn}{01AF} \pdfglyphtounicode{Uhornacute}{1EE8} \pdfglyphtounicode{Uhorndotbelow}{1EF0} \pdfglyphtounicode{Uhorngrave}{1EEA} \pdfglyphtounicode{Uhornhookabove}{1EEC} \pdfglyphtounicode{Uhorntilde}{1EEE} \pdfglyphtounicode{Uhungarumlaut}{0170} \pdfglyphtounicode{Uhungarumlautcyrillic}{04F2} \pdfglyphtounicode{Uinvertedbreve}{0216} \pdfglyphtounicode{Ukcyrillic}{0478} \pdfglyphtounicode{Umacron}{016A} \pdfglyphtounicode{Umacroncyrillic}{04EE} \pdfglyphtounicode{Umacrondieresis}{1E7A} \pdfglyphtounicode{Umonospace}{FF35} \pdfglyphtounicode{Uogonek}{0172} \pdfglyphtounicode{Upsilon}{03A5} \pdfglyphtounicode{Upsilon1}{03D2} \pdfglyphtounicode{Upsilonacutehooksymbolgreek}{03D3} \pdfglyphtounicode{Upsilonafrican}{01B1} \pdfglyphtounicode{Upsilondieresis}{03AB} \pdfglyphtounicode{Upsilondieresishooksymbolgreek}{03D4} \pdfglyphtounicode{Upsilonhooksymbol}{03D2} \pdfglyphtounicode{Upsilontonos}{038E} \pdfglyphtounicode{Uring}{016E} \pdfglyphtounicode{Ushortcyrillic}{040E} \pdfglyphtounicode{Usmall}{0075} \pdfglyphtounicode{Ustraightcyrillic}{04AE} \pdfglyphtounicode{Ustraightstrokecyrillic}{04B0} \pdfglyphtounicode{Utilde}{0168} \pdfglyphtounicode{Utildeacute}{1E78} \pdfglyphtounicode{Utildebelow}{1E74} \pdfglyphtounicode{V}{0056} \pdfglyphtounicode{Vcircle}{24CB} \pdfglyphtounicode{Vdotbelow}{1E7E} \pdfglyphtounicode{Vecyrillic}{0412} \pdfglyphtounicode{Vewarmenian}{054E} \pdfglyphtounicode{Vhook}{01B2} \pdfglyphtounicode{Vmonospace}{FF36} \pdfglyphtounicode{Voarmenian}{0548} \pdfglyphtounicode{Vsmall}{0076} \pdfglyphtounicode{Vtilde}{1E7C} \pdfglyphtounicode{W}{0057} \pdfglyphtounicode{Wacute}{1E82} \pdfglyphtounicode{Wcircle}{24CC} \pdfglyphtounicode{Wcircumflex}{0174} \pdfglyphtounicode{Wdieresis}{1E84} \pdfglyphtounicode{Wdotaccent}{1E86} \pdfglyphtounicode{Wdotbelow}{1E88} \pdfglyphtounicode{Wgrave}{1E80} \pdfglyphtounicode{Wmonospace}{FF37} \pdfglyphtounicode{Wsmall}{0077} \pdfglyphtounicode{X}{0058} \pdfglyphtounicode{Xcircle}{24CD} \pdfglyphtounicode{Xdieresis}{1E8C} \pdfglyphtounicode{Xdotaccent}{1E8A} \pdfglyphtounicode{Xeharmenian}{053D} \pdfglyphtounicode{Xi}{039E} \pdfglyphtounicode{Xmonospace}{FF38} \pdfglyphtounicode{Xsmall}{0078} \pdfglyphtounicode{Y}{0059} \pdfglyphtounicode{Yacute}{00DD} \pdfglyphtounicode{Yacutesmall}{00FD} \pdfglyphtounicode{Yatcyrillic}{0462} \pdfglyphtounicode{Ycircle}{24CE} \pdfglyphtounicode{Ycircumflex}{0176} \pdfglyphtounicode{Ydieresis}{0178} \pdfglyphtounicode{Ydieresissmall}{00FF} \pdfglyphtounicode{Ydotaccent}{1E8E} \pdfglyphtounicode{Ydotbelow}{1EF4} \pdfglyphtounicode{Yen}{00A5} \pdfglyphtounicode{Yericyrillic}{042B} \pdfglyphtounicode{Yerudieresiscyrillic}{04F8} \pdfglyphtounicode{Ygrave}{1EF2} \pdfglyphtounicode{Yhook}{01B3} \pdfglyphtounicode{Yhookabove}{1EF6} \pdfglyphtounicode{Yiarmenian}{0545} \pdfglyphtounicode{Yicyrillic}{0407} \pdfglyphtounicode{Yiwnarmenian}{0552} \pdfglyphtounicode{Ymonospace}{FF39} \pdfglyphtounicode{Ysmall}{0079} \pdfglyphtounicode{Ytilde}{1EF8} \pdfglyphtounicode{Yusbigcyrillic}{046A} \pdfglyphtounicode{Yusbigiotifiedcyrillic}{046C} \pdfglyphtounicode{Yuslittlecyrillic}{0466} \pdfglyphtounicode{Yuslittleiotifiedcyrillic}{0468} \pdfglyphtounicode{Z}{005A} \pdfglyphtounicode{Zaarmenian}{0536} \pdfglyphtounicode{Zacute}{0179} \pdfglyphtounicode{Zcaron}{017D} \pdfglyphtounicode{Zcaronsmall}{017E} \pdfglyphtounicode{Zcircle}{24CF} \pdfglyphtounicode{Zcircumflex}{1E90} \pdfglyphtounicode{Zdot}{017B} \pdfglyphtounicode{Zdotaccent}{017B} \pdfglyphtounicode{Zdotbelow}{1E92} \pdfglyphtounicode{Zecyrillic}{0417} \pdfglyphtounicode{Zedescendercyrillic}{0498} \pdfglyphtounicode{Zedieresiscyrillic}{04DE} \pdfglyphtounicode{Zeta}{0396} \pdfglyphtounicode{Zhearmenian}{053A} \pdfglyphtounicode{Zhebrevecyrillic}{04C1} \pdfglyphtounicode{Zhecyrillic}{0416} \pdfglyphtounicode{Zhedescendercyrillic}{0496} \pdfglyphtounicode{Zhedieresiscyrillic}{04DC} \pdfglyphtounicode{Zlinebelow}{1E94} \pdfglyphtounicode{Zmonospace}{FF3A} \pdfglyphtounicode{Zsmall}{007A} \pdfglyphtounicode{Zstroke}{01B5} \pdfglyphtounicode{a}{0061} \pdfglyphtounicode{aabengali}{0986} \pdfglyphtounicode{aacute}{00E1} \pdfglyphtounicode{aadeva}{0906} \pdfglyphtounicode{aagujarati}{0A86} \pdfglyphtounicode{aagurmukhi}{0A06} \pdfglyphtounicode{aamatragurmukhi}{0A3E} \pdfglyphtounicode{aarusquare}{3303} \pdfglyphtounicode{aavowelsignbengali}{09BE} \pdfglyphtounicode{aavowelsigndeva}{093E} \pdfglyphtounicode{aavowelsigngujarati}{0ABE} \pdfglyphtounicode{abbreviationmarkarmenian}{055F} \pdfglyphtounicode{abbreviationsigndeva}{0970} \pdfglyphtounicode{abengali}{0985} \pdfglyphtounicode{abopomofo}{311A} \pdfglyphtounicode{abreve}{0103} \pdfglyphtounicode{abreveacute}{1EAF} \pdfglyphtounicode{abrevecyrillic}{04D1} \pdfglyphtounicode{abrevedotbelow}{1EB7} \pdfglyphtounicode{abrevegrave}{1EB1} \pdfglyphtounicode{abrevehookabove}{1EB3} \pdfglyphtounicode{abrevetilde}{1EB5} \pdfglyphtounicode{acaron}{01CE} \pdfglyphtounicode{acircle}{24D0} \pdfglyphtounicode{acircumflex}{00E2} \pdfglyphtounicode{acircumflexacute}{1EA5} \pdfglyphtounicode{acircumflexdotbelow}{1EAD} \pdfglyphtounicode{acircumflexgrave}{1EA7} \pdfglyphtounicode{acircumflexhookabove}{1EA9} \pdfglyphtounicode{acircumflextilde}{1EAB} \pdfglyphtounicode{acute}{00B4} \pdfglyphtounicode{acutebelowcmb}{0317} \pdfglyphtounicode{acutecmb}{0301} \pdfglyphtounicode{acutecomb}{0301} \pdfglyphtounicode{acutedeva}{0954} \pdfglyphtounicode{acutelowmod}{02CF} \pdfglyphtounicode{acutetonecmb}{0341} \pdfglyphtounicode{acyrillic}{0430} \pdfglyphtounicode{adblgrave}{0201} \pdfglyphtounicode{addakgurmukhi}{0A71} \pdfglyphtounicode{adeva}{0905} \pdfglyphtounicode{adieresis}{00E4} \pdfglyphtounicode{adieresiscyrillic}{04D3} \pdfglyphtounicode{adieresismacron}{01DF} \pdfglyphtounicode{adotbelow}{1EA1} \pdfglyphtounicode{adotmacron}{01E1} \pdfglyphtounicode{ae}{00E6} \pdfglyphtounicode{aeacute}{01FD} \pdfglyphtounicode{aekorean}{3150} \pdfglyphtounicode{aemacron}{01E3} \pdfglyphtounicode{afii00208}{2015} \pdfglyphtounicode{afii08941}{20A4} \pdfglyphtounicode{afii10017}{0410} \pdfglyphtounicode{afii10018}{0411} \pdfglyphtounicode{afii10019}{0412} \pdfglyphtounicode{afii10020}{0413} \pdfglyphtounicode{afii10021}{0414} \pdfglyphtounicode{afii10022}{0415} \pdfglyphtounicode{afii10023}{0401} \pdfglyphtounicode{afii10024}{0416} \pdfglyphtounicode{afii10025}{0417} \pdfglyphtounicode{afii10026}{0418} \pdfglyphtounicode{afii10027}{0419} \pdfglyphtounicode{afii10028}{041A} \pdfglyphtounicode{afii10029}{041B} \pdfglyphtounicode{afii10030}{041C} \pdfglyphtounicode{afii10031}{041D} \pdfglyphtounicode{afii10032}{041E} \pdfglyphtounicode{afii10033}{041F} \pdfglyphtounicode{afii10034}{0420} \pdfglyphtounicode{afii10035}{0421} \pdfglyphtounicode{afii10036}{0422} \pdfglyphtounicode{afii10037}{0423} \pdfglyphtounicode{afii10038}{0424} \pdfglyphtounicode{afii10039}{0425} \pdfglyphtounicode{afii10040}{0426} \pdfglyphtounicode{afii10041}{0427} \pdfglyphtounicode{afii10042}{0428} \pdfglyphtounicode{afii10043}{0429} \pdfglyphtounicode{afii10044}{042A} \pdfglyphtounicode{afii10045}{042B} \pdfglyphtounicode{afii10046}{042C} \pdfglyphtounicode{afii10047}{042D} \pdfglyphtounicode{afii10048}{042E} \pdfglyphtounicode{afii10049}{042F} \pdfglyphtounicode{afii10050}{0490} \pdfglyphtounicode{afii10051}{0402} \pdfglyphtounicode{afii10052}{0403} \pdfglyphtounicode{afii10053}{0404} \pdfglyphtounicode{afii10054}{0405} \pdfglyphtounicode{afii10055}{0406} \pdfglyphtounicode{afii10056}{0407} \pdfglyphtounicode{afii10057}{0408} \pdfglyphtounicode{afii10058}{0409} \pdfglyphtounicode{afii10059}{040A} \pdfglyphtounicode{afii10060}{040B} \pdfglyphtounicode{afii10061}{040C} \pdfglyphtounicode{afii10062}{040E} \pdfglyphtounicode{afii10063}{F6C4} \pdfglyphtounicode{afii10064}{F6C5} \pdfglyphtounicode{afii10065}{0430} \pdfglyphtounicode{afii10066}{0431} \pdfglyphtounicode{afii10067}{0432} \pdfglyphtounicode{afii10068}{0433} \pdfglyphtounicode{afii10069}{0434} \pdfglyphtounicode{afii10070}{0435} \pdfglyphtounicode{afii10071}{0451} \pdfglyphtounicode{afii10072}{0436} \pdfglyphtounicode{afii10073}{0437} \pdfglyphtounicode{afii10074}{0438} \pdfglyphtounicode{afii10075}{0439} \pdfglyphtounicode{afii10076}{043A} \pdfglyphtounicode{afii10077}{043B} \pdfglyphtounicode{afii10078}{043C} \pdfglyphtounicode{afii10079}{043D} \pdfglyphtounicode{afii10080}{043E} \pdfglyphtounicode{afii10081}{043F} \pdfglyphtounicode{afii10082}{0440} \pdfglyphtounicode{afii10083}{0441} \pdfglyphtounicode{afii10084}{0442} \pdfglyphtounicode{afii10085}{0443} \pdfglyphtounicode{afii10086}{0444} \pdfglyphtounicode{afii10087}{0445} \pdfglyphtounicode{afii10088}{0446} \pdfglyphtounicode{afii10089}{0447} \pdfglyphtounicode{afii10090}{0448} \pdfglyphtounicode{afii10091}{0449} \pdfglyphtounicode{afii10092}{044A} \pdfglyphtounicode{afii10093}{044B} \pdfglyphtounicode{afii10094}{044C} \pdfglyphtounicode{afii10095}{044D} \pdfglyphtounicode{afii10096}{044E} \pdfglyphtounicode{afii10097}{044F} \pdfglyphtounicode{afii10098}{0491} \pdfglyphtounicode{afii10099}{0452} \pdfglyphtounicode{afii10100}{0453} \pdfglyphtounicode{afii10101}{0454} \pdfglyphtounicode{afii10102}{0455} \pdfglyphtounicode{afii10103}{0456} \pdfglyphtounicode{afii10104}{0457} \pdfglyphtounicode{afii10105}{0458} \pdfglyphtounicode{afii10106}{0459} \pdfglyphtounicode{afii10107}{045A} \pdfglyphtounicode{afii10108}{045B} \pdfglyphtounicode{afii10109}{045C} \pdfglyphtounicode{afii10110}{045E} \pdfglyphtounicode{afii10145}{040F} \pdfglyphtounicode{afii10146}{0462} \pdfglyphtounicode{afii10147}{0472} \pdfglyphtounicode{afii10148}{0474} \pdfglyphtounicode{afii10192}{F6C6} \pdfglyphtounicode{afii10193}{045F} \pdfglyphtounicode{afii10194}{0463} \pdfglyphtounicode{afii10195}{0473} \pdfglyphtounicode{afii10196}{0475} \pdfglyphtounicode{afii10831}{F6C7} \pdfglyphtounicode{afii10832}{F6C8} \pdfglyphtounicode{afii10846}{04D9} \pdfglyphtounicode{afii299}{200E} \pdfglyphtounicode{afii300}{200F} \pdfglyphtounicode{afii301}{200D} \pdfglyphtounicode{afii57381}{066A} \pdfglyphtounicode{afii57388}{060C} \pdfglyphtounicode{afii57392}{0660} \pdfglyphtounicode{afii57393}{0661} \pdfglyphtounicode{afii57394}{0662} \pdfglyphtounicode{afii57395}{0663} \pdfglyphtounicode{afii57396}{0664} \pdfglyphtounicode{afii57397}{0665} \pdfglyphtounicode{afii57398}{0666} \pdfglyphtounicode{afii57399}{0667} \pdfglyphtounicode{afii57400}{0668} \pdfglyphtounicode{afii57401}{0669} \pdfglyphtounicode{afii57403}{061B} \pdfglyphtounicode{afii57407}{061F} \pdfglyphtounicode{afii57409}{0621} \pdfglyphtounicode{afii57410}{0622} \pdfglyphtounicode{afii57411}{0623} \pdfglyphtounicode{afii57412}{0624} \pdfglyphtounicode{afii57413}{0625} \pdfglyphtounicode{afii57414}{0626} \pdfglyphtounicode{afii57415}{0627} \pdfglyphtounicode{afii57416}{0628} \pdfglyphtounicode{afii57417}{0629} \pdfglyphtounicode{afii57418}{062A} \pdfglyphtounicode{afii57419}{062B} \pdfglyphtounicode{afii57420}{062C} \pdfglyphtounicode{afii57421}{062D} \pdfglyphtounicode{afii57422}{062E} \pdfglyphtounicode{afii57423}{062F} \pdfglyphtounicode{afii57424}{0630} \pdfglyphtounicode{afii57425}{0631} \pdfglyphtounicode{afii57426}{0632} \pdfglyphtounicode{afii57427}{0633} \pdfglyphtounicode{afii57428}{0634} \pdfglyphtounicode{afii57429}{0635} \pdfglyphtounicode{afii57430}{0636} \pdfglyphtounicode{afii57431}{0637} \pdfglyphtounicode{afii57432}{0638} \pdfglyphtounicode{afii57433}{0639} \pdfglyphtounicode{afii57434}{063A} \pdfglyphtounicode{afii57440}{0640} \pdfglyphtounicode{afii57441}{0641} \pdfglyphtounicode{afii57442}{0642} \pdfglyphtounicode{afii57443}{0643} \pdfglyphtounicode{afii57444}{0644} \pdfglyphtounicode{afii57445}{0645} \pdfglyphtounicode{afii57446}{0646} \pdfglyphtounicode{afii57448}{0648} \pdfglyphtounicode{afii57449}{0649} \pdfglyphtounicode{afii57450}{064A} \pdfglyphtounicode{afii57451}{064B} \pdfglyphtounicode{afii57452}{064C} \pdfglyphtounicode{afii57453}{064D} \pdfglyphtounicode{afii57454}{064E} \pdfglyphtounicode{afii57455}{064F} \pdfglyphtounicode{afii57456}{0650} \pdfglyphtounicode{afii57457}{0651} \pdfglyphtounicode{afii57458}{0652} \pdfglyphtounicode{afii57470}{0647} \pdfglyphtounicode{afii57505}{06A4} \pdfglyphtounicode{afii57506}{067E} \pdfglyphtounicode{afii57507}{0686} \pdfglyphtounicode{afii57508}{0698} \pdfglyphtounicode{afii57509}{06AF} \pdfglyphtounicode{afii57511}{0679} \pdfglyphtounicode{afii57512}{0688} \pdfglyphtounicode{afii57513}{0691} \pdfglyphtounicode{afii57514}{06BA} \pdfglyphtounicode{afii57519}{06D2} \pdfglyphtounicode{afii57534}{06D5} \pdfglyphtounicode{afii57636}{20AA} \pdfglyphtounicode{afii57645}{05BE} \pdfglyphtounicode{afii57658}{05C3} \pdfglyphtounicode{afii57664}{05D0} \pdfglyphtounicode{afii57665}{05D1} \pdfglyphtounicode{afii57666}{05D2} \pdfglyphtounicode{afii57667}{05D3} \pdfglyphtounicode{afii57668}{05D4} \pdfglyphtounicode{afii57669}{05D5} \pdfglyphtounicode{afii57670}{05D6} \pdfglyphtounicode{afii57671}{05D7} \pdfglyphtounicode{afii57672}{05D8} \pdfglyphtounicode{afii57673}{05D9} \pdfglyphtounicode{afii57674}{05DA} \pdfglyphtounicode{afii57675}{05DB} \pdfglyphtounicode{afii57676}{05DC} \pdfglyphtounicode{afii57677}{05DD} \pdfglyphtounicode{afii57678}{05DE} \pdfglyphtounicode{afii57679}{05DF} \pdfglyphtounicode{afii57680}{05E0} \pdfglyphtounicode{afii57681}{05E1} \pdfglyphtounicode{afii57682}{05E2} \pdfglyphtounicode{afii57683}{05E3} \pdfglyphtounicode{afii57684}{05E4} \pdfglyphtounicode{afii57685}{05E5} \pdfglyphtounicode{afii57686}{05E6} \pdfglyphtounicode{afii57687}{05E7} \pdfglyphtounicode{afii57688}{05E8} \pdfglyphtounicode{afii57689}{05E9} \pdfglyphtounicode{afii57690}{05EA} \pdfglyphtounicode{afii57694}{FB2A} \pdfglyphtounicode{afii57695}{FB2B} \pdfglyphtounicode{afii57700}{FB4B} \pdfglyphtounicode{afii57705}{FB1F} \pdfglyphtounicode{afii57716}{05F0} \pdfglyphtounicode{afii57717}{05F1} \pdfglyphtounicode{afii57718}{05F2} \pdfglyphtounicode{afii57723}{FB35} \pdfglyphtounicode{afii57793}{05B4} \pdfglyphtounicode{afii57794}{05B5} \pdfglyphtounicode{afii57795}{05B6} \pdfglyphtounicode{afii57796}{05BB} \pdfglyphtounicode{afii57797}{05B8} \pdfglyphtounicode{afii57798}{05B7} \pdfglyphtounicode{afii57799}{05B0} \pdfglyphtounicode{afii57800}{05B2} \pdfglyphtounicode{afii57801}{05B1} \pdfglyphtounicode{afii57802}{05B3} \pdfglyphtounicode{afii57803}{05C2} \pdfglyphtounicode{afii57804}{05C1} \pdfglyphtounicode{afii57806}{05B9} \pdfglyphtounicode{afii57807}{05BC} \pdfglyphtounicode{afii57839}{05BD} \pdfglyphtounicode{afii57841}{05BF} \pdfglyphtounicode{afii57842}{05C0} \pdfglyphtounicode{afii57929}{02BC} \pdfglyphtounicode{afii61248}{2105} \pdfglyphtounicode{afii61289}{2113} \pdfglyphtounicode{afii61352}{2116} \pdfglyphtounicode{afii61573}{202C} \pdfglyphtounicode{afii61574}{202D} \pdfglyphtounicode{afii61575}{202E} \pdfglyphtounicode{afii61664}{200C} \pdfglyphtounicode{afii63167}{066D} \pdfglyphtounicode{afii64937}{02BD} \pdfglyphtounicode{agrave}{00E0} \pdfglyphtounicode{agujarati}{0A85} \pdfglyphtounicode{agurmukhi}{0A05} \pdfglyphtounicode{ahiragana}{3042} \pdfglyphtounicode{ahookabove}{1EA3} \pdfglyphtounicode{aibengali}{0990} \pdfglyphtounicode{aibopomofo}{311E} \pdfglyphtounicode{aideva}{0910} \pdfglyphtounicode{aiecyrillic}{04D5} \pdfglyphtounicode{aigujarati}{0A90} \pdfglyphtounicode{aigurmukhi}{0A10} \pdfglyphtounicode{aimatragurmukhi}{0A48} \pdfglyphtounicode{ainarabic}{0639} \pdfglyphtounicode{ainfinalarabic}{FECA} \pdfglyphtounicode{aininitialarabic}{FECB} \pdfglyphtounicode{ainmedialarabic}{FECC} \pdfglyphtounicode{ainvertedbreve}{0203} \pdfglyphtounicode{aivowelsignbengali}{09C8} \pdfglyphtounicode{aivowelsigndeva}{0948} \pdfglyphtounicode{aivowelsigngujarati}{0AC8} \pdfglyphtounicode{akatakana}{30A2} \pdfglyphtounicode{akatakanahalfwidth}{FF71} \pdfglyphtounicode{akorean}{314F} \pdfglyphtounicode{alef}{05D0} \pdfglyphtounicode{alefarabic}{0627} \pdfglyphtounicode{alefdageshhebrew}{FB30} \pdfglyphtounicode{aleffinalarabic}{FE8E} \pdfglyphtounicode{alefhamzaabovearabic}{0623} \pdfglyphtounicode{alefhamzaabovefinalarabic}{FE84} \pdfglyphtounicode{alefhamzabelowarabic}{0625} \pdfglyphtounicode{alefhamzabelowfinalarabic}{FE88} \pdfglyphtounicode{alefhebrew}{05D0} \pdfglyphtounicode{aleflamedhebrew}{FB4F} \pdfglyphtounicode{alefmaddaabovearabic}{0622} \pdfglyphtounicode{alefmaddaabovefinalarabic}{FE82} \pdfglyphtounicode{alefmaksuraarabic}{0649} \pdfglyphtounicode{alefmaksurafinalarabic}{FEF0} \pdfglyphtounicode{alefmaksurainitialarabic}{FEF3} \pdfglyphtounicode{alefmaksuramedialarabic}{FEF4} \pdfglyphtounicode{alefpatahhebrew}{FB2E} \pdfglyphtounicode{alefqamatshebrew}{FB2F} \pdfglyphtounicode{aleph}{2135} \pdfglyphtounicode{allequal}{224C} \pdfglyphtounicode{alpha}{03B1} \pdfglyphtounicode{alphatonos}{03AC} \pdfglyphtounicode{amacron}{0101} \pdfglyphtounicode{amonospace}{FF41} \pdfglyphtounicode{ampersand}{0026} \pdfglyphtounicode{ampersandmonospace}{FF06} \pdfglyphtounicode{ampersandsmall}{0026} \pdfglyphtounicode{amsquare}{33C2} \pdfglyphtounicode{anbopomofo}{3122} \pdfglyphtounicode{angbopomofo}{3124} \pdfglyphtounicode{angbracketleft}{27E8} \pdfglyphtounicode{angbracketright}{27E9} \pdfglyphtounicode{angkhankhuthai}{0E5A} \pdfglyphtounicode{angle}{2220} \pdfglyphtounicode{anglebracketleft}{3008} \pdfglyphtounicode{anglebracketleftvertical}{FE3F} \pdfglyphtounicode{anglebracketright}{3009} \pdfglyphtounicode{anglebracketrightvertical}{FE40} \pdfglyphtounicode{angleleft}{2329} \pdfglyphtounicode{angleright}{232A} \pdfglyphtounicode{angstrom}{212B} \pdfglyphtounicode{anoteleia}{0387} \pdfglyphtounicode{anticlockwise}{27F2} \pdfglyphtounicode{anudattadeva}{0952} \pdfglyphtounicode{anusvarabengali}{0982} \pdfglyphtounicode{anusvaradeva}{0902} \pdfglyphtounicode{anusvaragujarati}{0A82} \pdfglyphtounicode{aogonek}{0105} \pdfglyphtounicode{apaatosquare}{3300} \pdfglyphtounicode{aparen}{249C} \pdfglyphtounicode{apostrophearmenian}{055A} \pdfglyphtounicode{apostrophemod}{02BC} \pdfglyphtounicode{apple}{F8FF} \pdfglyphtounicode{approaches}{2250} \pdfglyphtounicode{approxequal}{2248} \pdfglyphtounicode{approxequalorimage}{2252} \pdfglyphtounicode{approximatelyequal}{2245} \pdfglyphtounicode{approxorequal}{224A} \pdfglyphtounicode{araeaekorean}{318E} \pdfglyphtounicode{araeakorean}{318D} \pdfglyphtounicode{arc}{2312} \pdfglyphtounicode{archleftdown}{21B6} \pdfglyphtounicode{archrightdown}{21B7} \pdfglyphtounicode{arighthalfring}{1E9A} \pdfglyphtounicode{aring}{00E5} \pdfglyphtounicode{aringacute}{01FB} \pdfglyphtounicode{aringbelow}{1E01} \pdfglyphtounicode{arrowboth}{2194} \pdfglyphtounicode{arrowbothv}{2195} \pdfglyphtounicode{arrowdashdown}{21E3} \pdfglyphtounicode{arrowdashleft}{21E0} \pdfglyphtounicode{arrowdashright}{21E2} \pdfglyphtounicode{arrowdashup}{21E1} \pdfglyphtounicode{arrowdblboth}{21D4} \pdfglyphtounicode{arrowdblbothv}{21D5} \pdfglyphtounicode{arrowdbldown}{21D3} \pdfglyphtounicode{arrowdblleft}{21D0} \pdfglyphtounicode{arrowdblright}{21D2} \pdfglyphtounicode{arrowdblup}{21D1} \pdfglyphtounicode{arrowdown}{2193} \pdfglyphtounicode{arrowdownleft}{2199} \pdfglyphtounicode{arrowdownright}{2198} \pdfglyphtounicode{arrowdownwhite}{21E9} \pdfglyphtounicode{arrowheaddownmod}{02C5} \pdfglyphtounicode{arrowheadleftmod}{02C2} \pdfglyphtounicode{arrowheadrightmod}{02C3} \pdfglyphtounicode{arrowheadupmod}{02C4} \pdfglyphtounicode{arrowhorizex}{F8E7} \pdfglyphtounicode{arrowleft}{2190} \pdfglyphtounicode{arrowleftbothalf}{21BD} \pdfglyphtounicode{arrowleftdbl}{21D0} \pdfglyphtounicode{arrowleftdblstroke}{21CD} \pdfglyphtounicode{arrowleftoverright}{21C6} \pdfglyphtounicode{arrowlefttophalf}{21BC} \pdfglyphtounicode{arrowleftwhite}{21E6} \pdfglyphtounicode{arrownortheast}{2197} \pdfglyphtounicode{arrownorthwest}{2196} \pdfglyphtounicode{arrowparrleftright}{21C6} \pdfglyphtounicode{arrowparrrightleft}{21C4} \pdfglyphtounicode{arrowright}{2192} \pdfglyphtounicode{arrowrightbothalf}{21C1} \pdfglyphtounicode{arrowrightdblstroke}{21CF} \pdfglyphtounicode{arrowrightheavy}{279E} \pdfglyphtounicode{arrowrightoverleft}{21C4} \pdfglyphtounicode{arrowrighttophalf}{21C0} \pdfglyphtounicode{arrowrightwhite}{21E8} \pdfglyphtounicode{arrowsoutheast}{2198} \pdfglyphtounicode{arrowsouthwest}{2199} \pdfglyphtounicode{arrowtableft}{21E4} \pdfglyphtounicode{arrowtabright}{21E5} \pdfglyphtounicode{arrowtailleft}{21A2} \pdfglyphtounicode{arrowtailright}{21A3} \pdfglyphtounicode{arrowtripleleft}{21DA} \pdfglyphtounicode{arrowtripleright}{21DB} \pdfglyphtounicode{arrowup}{2191} \pdfglyphtounicode{arrowupdn}{2195} \pdfglyphtounicode{arrowupdnbse}{21A8} \pdfglyphtounicode{arrowupdownbase}{21A8} \pdfglyphtounicode{arrowupleft}{2196} \pdfglyphtounicode{arrowupleftofdown}{21C5} \pdfglyphtounicode{arrowupright}{2197} \pdfglyphtounicode{arrowupwhite}{21E7} \pdfglyphtounicode{arrowvertex}{F8E6} \pdfglyphtounicode{asciicircum}{005E} \pdfglyphtounicode{asciicircummonospace}{FF3E} \pdfglyphtounicode{asciitilde}{007E} \pdfglyphtounicode{asciitildemonospace}{FF5E} \pdfglyphtounicode{ascript}{0251} \pdfglyphtounicode{ascriptturned}{0252} \pdfglyphtounicode{asmallhiragana}{3041} \pdfglyphtounicode{asmallkatakana}{30A1} \pdfglyphtounicode{asmallkatakanahalfwidth}{FF67} \pdfglyphtounicode{asterisk}{002A} \pdfglyphtounicode{asteriskaltonearabic}{066D} \pdfglyphtounicode{asteriskarabic}{066D} \pdfglyphtounicode{asteriskcentered}{2217} \pdfglyphtounicode{asteriskmath}{2217} \pdfglyphtounicode{asteriskmonospace}{FF0A} \pdfglyphtounicode{asterisksmall}{FE61} \pdfglyphtounicode{asterism}{2042} \pdfglyphtounicode{asuperior}{0061} \pdfglyphtounicode{asymptoticallyequal}{2243} \pdfglyphtounicode{at}{0040} \pdfglyphtounicode{atilde}{00E3} \pdfglyphtounicode{atmonospace}{FF20} \pdfglyphtounicode{atsmall}{FE6B} \pdfglyphtounicode{aturned}{0250} \pdfglyphtounicode{aubengali}{0994} \pdfglyphtounicode{aubopomofo}{3120} \pdfglyphtounicode{audeva}{0914} \pdfglyphtounicode{augujarati}{0A94} \pdfglyphtounicode{augurmukhi}{0A14} \pdfglyphtounicode{aulengthmarkbengali}{09D7} \pdfglyphtounicode{aumatragurmukhi}{0A4C} \pdfglyphtounicode{auvowelsignbengali}{09CC} \pdfglyphtounicode{auvowelsigndeva}{094C} \pdfglyphtounicode{auvowelsigngujarati}{0ACC} \pdfglyphtounicode{avagrahadeva}{093D} \pdfglyphtounicode{aybarmenian}{0561} \pdfglyphtounicode{ayin}{05E2} \pdfglyphtounicode{ayinaltonehebrew}{FB20} \pdfglyphtounicode{ayinhebrew}{05E2} \pdfglyphtounicode{b}{0062} \pdfglyphtounicode{babengali}{09AC} \pdfglyphtounicode{backslash}{005C} \pdfglyphtounicode{backslashmonospace}{FF3C} \pdfglyphtounicode{badeva}{092C} \pdfglyphtounicode{bagujarati}{0AAC} \pdfglyphtounicode{bagurmukhi}{0A2C} \pdfglyphtounicode{bahiragana}{3070} \pdfglyphtounicode{bahtthai}{0E3F} \pdfglyphtounicode{bakatakana}{30D0} \pdfglyphtounicode{bar}{007C} \pdfglyphtounicode{bardbl}{2225} \pdfglyphtounicode{barmonospace}{FF5C} \pdfglyphtounicode{bbopomofo}{3105} \pdfglyphtounicode{bcircle}{24D1} \pdfglyphtounicode{bdotaccent}{1E03} \pdfglyphtounicode{bdotbelow}{1E05} \pdfglyphtounicode{beamedsixteenthnotes}{266C} \pdfglyphtounicode{because}{2235} \pdfglyphtounicode{becyrillic}{0431} \pdfglyphtounicode{beharabic}{0628} \pdfglyphtounicode{behfinalarabic}{FE90} \pdfglyphtounicode{behinitialarabic}{FE91} \pdfglyphtounicode{behiragana}{3079} \pdfglyphtounicode{behmedialarabic}{FE92} \pdfglyphtounicode{behmeeminitialarabic}{FC9F} \pdfglyphtounicode{behmeemisolatedarabic}{FC08} \pdfglyphtounicode{behnoonfinalarabic}{FC6D} \pdfglyphtounicode{bekatakana}{30D9} \pdfglyphtounicode{benarmenian}{0562} \pdfglyphtounicode{bet}{05D1} \pdfglyphtounicode{beta}{03B2} \pdfglyphtounicode{betasymbolgreek}{03D0} \pdfglyphtounicode{betdagesh}{FB31} \pdfglyphtounicode{betdageshhebrew}{FB31} \pdfglyphtounicode{beth}{2136} \pdfglyphtounicode{bethebrew}{05D1} \pdfglyphtounicode{betrafehebrew}{FB4C} \pdfglyphtounicode{between}{226C} \pdfglyphtounicode{bhabengali}{09AD} \pdfglyphtounicode{bhadeva}{092D} \pdfglyphtounicode{bhagujarati}{0AAD} \pdfglyphtounicode{bhagurmukhi}{0A2D} \pdfglyphtounicode{bhook}{0253} \pdfglyphtounicode{bihiragana}{3073} \pdfglyphtounicode{bikatakana}{30D3} \pdfglyphtounicode{bilabialclick}{0298} \pdfglyphtounicode{bindigurmukhi}{0A02} \pdfglyphtounicode{birusquare}{3331} \pdfglyphtounicode{blackcircle}{25CF} \pdfglyphtounicode{blackdiamond}{25C6} \pdfglyphtounicode{blackdownpointingtriangle}{25BC} \pdfglyphtounicode{blackleftpointingpointer}{25C4} \pdfglyphtounicode{blackleftpointingtriangle}{25C0} \pdfglyphtounicode{blacklenticularbracketleft}{3010} \pdfglyphtounicode{blacklenticularbracketleftvertical}{FE3B} \pdfglyphtounicode{blacklenticularbracketright}{3011} \pdfglyphtounicode{blacklenticularbracketrightvertical}{FE3C} \pdfglyphtounicode{blacklowerlefttriangle}{25E3} \pdfglyphtounicode{blacklowerrighttriangle}{25E2} \pdfglyphtounicode{blackrectangle}{25AC} \pdfglyphtounicode{blackrightpointingpointer}{25BA} \pdfglyphtounicode{blackrightpointingtriangle}{25B6} \pdfglyphtounicode{blacksmallsquare}{25AA} \pdfglyphtounicode{blacksmilingface}{263B} \pdfglyphtounicode{blacksquare}{25A0} \pdfglyphtounicode{blackstar}{2605} \pdfglyphtounicode{blackupperlefttriangle}{25E4} \pdfglyphtounicode{blackupperrighttriangle}{25E5} \pdfglyphtounicode{blackuppointingsmalltriangle}{25B4} \pdfglyphtounicode{blackuppointingtriangle}{25B2} \pdfglyphtounicode{blank}{2423} \pdfglyphtounicode{blinebelow}{1E07} \pdfglyphtounicode{block}{2588} \pdfglyphtounicode{bmonospace}{FF42} \pdfglyphtounicode{bobaimaithai}{0E1A} \pdfglyphtounicode{bohiragana}{307C} \pdfglyphtounicode{bokatakana}{30DC} \pdfglyphtounicode{bparen}{249D} \pdfglyphtounicode{bqsquare}{33C3} \pdfglyphtounicode{braceex}{F8F4} \pdfglyphtounicode{braceleft}{007B} \pdfglyphtounicode{braceleftbt}{F8F3} \pdfglyphtounicode{braceleftmid}{F8F2} \pdfglyphtounicode{braceleftmonospace}{FF5B} \pdfglyphtounicode{braceleftsmall}{FE5B} \pdfglyphtounicode{bracelefttp}{F8F1} \pdfglyphtounicode{braceleftvertical}{FE37} \pdfglyphtounicode{braceright}{007D} \pdfglyphtounicode{bracerightbt}{F8FE} \pdfglyphtounicode{bracerightmid}{F8FD} \pdfglyphtounicode{bracerightmonospace}{FF5D} \pdfglyphtounicode{bracerightsmall}{FE5C} \pdfglyphtounicode{bracerighttp}{F8FC} \pdfglyphtounicode{bracerightvertical}{FE38} \pdfglyphtounicode{bracketleft}{005B} \pdfglyphtounicode{bracketleftbt}{F8F0} \pdfglyphtounicode{bracketleftex}{F8EF} \pdfglyphtounicode{bracketleftmonospace}{FF3B} \pdfglyphtounicode{bracketlefttp}{F8EE} \pdfglyphtounicode{bracketright}{005D} \pdfglyphtounicode{bracketrightbt}{F8FB} \pdfglyphtounicode{bracketrightex}{F8FA} \pdfglyphtounicode{bracketrightmonospace}{FF3D} \pdfglyphtounicode{bracketrighttp}{F8F9} \pdfglyphtounicode{breve}{02D8} \pdfglyphtounicode{brevebelowcmb}{032E} \pdfglyphtounicode{brevecmb}{0306} \pdfglyphtounicode{breveinvertedbelowcmb}{032F} \pdfglyphtounicode{breveinvertedcmb}{0311} \pdfglyphtounicode{breveinverteddoublecmb}{0361} \pdfglyphtounicode{bridgebelowcmb}{032A} \pdfglyphtounicode{bridgeinvertedbelowcmb}{033A} \pdfglyphtounicode{brokenbar}{00A6} \pdfglyphtounicode{bstroke}{0180} \pdfglyphtounicode{bsuperior}{0062} \pdfglyphtounicode{btopbar}{0183} \pdfglyphtounicode{buhiragana}{3076} \pdfglyphtounicode{bukatakana}{30D6} \pdfglyphtounicode{bullet}{2022} \pdfglyphtounicode{bulletinverse}{25D8} \pdfglyphtounicode{bulletoperator}{2219} \pdfglyphtounicode{bullseye}{25CE} \pdfglyphtounicode{c}{0063} \pdfglyphtounicode{caarmenian}{056E} \pdfglyphtounicode{cabengali}{099A} \pdfglyphtounicode{cacute}{0107} \pdfglyphtounicode{cadeva}{091A} \pdfglyphtounicode{cagujarati}{0A9A} \pdfglyphtounicode{cagurmukhi}{0A1A} \pdfglyphtounicode{calsquare}{3388} \pdfglyphtounicode{candrabindubengali}{0981} \pdfglyphtounicode{candrabinducmb}{0310} \pdfglyphtounicode{candrabindudeva}{0901} \pdfglyphtounicode{candrabindugujarati}{0A81} \pdfglyphtounicode{capslock}{21EA} \pdfglyphtounicode{careof}{2105} \pdfglyphtounicode{caron}{02C7} \pdfglyphtounicode{caronbelowcmb}{032C} \pdfglyphtounicode{caroncmb}{030C} \pdfglyphtounicode{carriagereturn}{21B5} \pdfglyphtounicode{cbopomofo}{3118} \pdfglyphtounicode{ccaron}{010D} \pdfglyphtounicode{ccedilla}{00E7} \pdfglyphtounicode{ccedillaacute}{1E09} \pdfglyphtounicode{ccircle}{24D2} \pdfglyphtounicode{ccircumflex}{0109} \pdfglyphtounicode{ccurl}{0255} \pdfglyphtounicode{cdot}{010B} \pdfglyphtounicode{cdotaccent}{010B} \pdfglyphtounicode{cdsquare}{33C5} \pdfglyphtounicode{cedilla}{00B8} \pdfglyphtounicode{cedillacmb}{0327} \pdfglyphtounicode{ceilingleft}{2308} \pdfglyphtounicode{ceilingright}{2309} \pdfglyphtounicode{cent}{00A2} \pdfglyphtounicode{centigrade}{2103} \pdfglyphtounicode{centinferior}{00A2} \pdfglyphtounicode{centmonospace}{FFE0} \pdfglyphtounicode{centoldstyle}{00A2} \pdfglyphtounicode{centsuperior}{00A2} \pdfglyphtounicode{chaarmenian}{0579} \pdfglyphtounicode{chabengali}{099B} \pdfglyphtounicode{chadeva}{091B} \pdfglyphtounicode{chagujarati}{0A9B} \pdfglyphtounicode{chagurmukhi}{0A1B} \pdfglyphtounicode{chbopomofo}{3114} \pdfglyphtounicode{cheabkhasiancyrillic}{04BD} \pdfglyphtounicode{check}{2713} \pdfglyphtounicode{checkmark}{2713} \pdfglyphtounicode{checyrillic}{0447} \pdfglyphtounicode{chedescenderabkhasiancyrillic}{04BF} \pdfglyphtounicode{chedescendercyrillic}{04B7} \pdfglyphtounicode{chedieresiscyrillic}{04F5} \pdfglyphtounicode{cheharmenian}{0573} \pdfglyphtounicode{chekhakassiancyrillic}{04CC} \pdfglyphtounicode{cheverticalstrokecyrillic}{04B9} \pdfglyphtounicode{chi}{03C7} \pdfglyphtounicode{chieuchacirclekorean}{3277} \pdfglyphtounicode{chieuchaparenkorean}{3217} \pdfglyphtounicode{chieuchcirclekorean}{3269} \pdfglyphtounicode{chieuchkorean}{314A} \pdfglyphtounicode{chieuchparenkorean}{3209} \pdfglyphtounicode{chochangthai}{0E0A} \pdfglyphtounicode{chochanthai}{0E08} \pdfglyphtounicode{chochingthai}{0E09} \pdfglyphtounicode{chochoethai}{0E0C} \pdfglyphtounicode{chook}{0188} \pdfglyphtounicode{cieucacirclekorean}{3276} \pdfglyphtounicode{cieucaparenkorean}{3216} \pdfglyphtounicode{cieuccirclekorean}{3268} \pdfglyphtounicode{cieuckorean}{3148} \pdfglyphtounicode{cieucparenkorean}{3208} \pdfglyphtounicode{cieucuparenkorean}{321C} \pdfglyphtounicode{circle}{25CB} \pdfglyphtounicode{circleR}{00AE} \pdfglyphtounicode{circleS}{24C8} \pdfglyphtounicode{circleasterisk}{229B} \pdfglyphtounicode{circlecopyrt}{20DD} \pdfglyphtounicode{circledivide}{2298} \pdfglyphtounicode{circledot}{2299} \pdfglyphtounicode{circleequal}{229C} \pdfglyphtounicode{circleminus}{2296} \pdfglyphtounicode{circlemultiply}{2297} \pdfglyphtounicode{circleot}{2299} \pdfglyphtounicode{circleplus}{2295} \pdfglyphtounicode{circlepostalmark}{3036} \pdfglyphtounicode{circlering}{229A} \pdfglyphtounicode{circlewithlefthalfblack}{25D0} \pdfglyphtounicode{circlewithrighthalfblack}{25D1} \pdfglyphtounicode{circumflex}{02C6} \pdfglyphtounicode{circumflexbelowcmb}{032D} \pdfglyphtounicode{circumflexcmb}{0302} \pdfglyphtounicode{clear}{2327} \pdfglyphtounicode{clickalveolar}{01C2} \pdfglyphtounicode{clickdental}{01C0} \pdfglyphtounicode{clicklateral}{01C1} \pdfglyphtounicode{clickretroflex}{01C3} \pdfglyphtounicode{clockwise}{27F3} \pdfglyphtounicode{club}{2663} \pdfglyphtounicode{clubsuitblack}{2663} \pdfglyphtounicode{clubsuitwhite}{2667} \pdfglyphtounicode{cmcubedsquare}{33A4} \pdfglyphtounicode{cmonospace}{FF43} \pdfglyphtounicode{cmsquaredsquare}{33A0} \pdfglyphtounicode{coarmenian}{0581} \pdfglyphtounicode{colon}{003A} \pdfglyphtounicode{colonmonetary}{20A1} \pdfglyphtounicode{colonmonospace}{FF1A} \pdfglyphtounicode{colonsign}{20A1} \pdfglyphtounicode{colonsmall}{FE55} \pdfglyphtounicode{colontriangularhalfmod}{02D1} \pdfglyphtounicode{colontriangularmod}{02D0} \pdfglyphtounicode{comma}{002C} \pdfglyphtounicode{commaabovecmb}{0313} \pdfglyphtounicode{commaaboverightcmb}{0315} \pdfglyphtounicode{commaaccent}{F6C3} \pdfglyphtounicode{commaarabic}{060C} \pdfglyphtounicode{commaarmenian}{055D} \pdfglyphtounicode{commainferior}{002C} \pdfglyphtounicode{commamonospace}{FF0C} \pdfglyphtounicode{commareversedabovecmb}{0314} \pdfglyphtounicode{commareversedmod}{02BD} \pdfglyphtounicode{commasmall}{FE50} \pdfglyphtounicode{commasuperior}{002C} \pdfglyphtounicode{commaturnedabovecmb}{0312} \pdfglyphtounicode{commaturnedmod}{02BB} \pdfglyphtounicode{compass}{263C} \pdfglyphtounicode{complement}{2201} \pdfglyphtounicode{compwordmark}{200C} \pdfglyphtounicode{congruent}{2245} \pdfglyphtounicode{contourintegral}{222E} \pdfglyphtounicode{control}{2303} \pdfglyphtounicode{controlACK}{0006} \pdfglyphtounicode{controlBEL}{0007} \pdfglyphtounicode{controlBS}{0008} \pdfglyphtounicode{controlCAN}{0018} \pdfglyphtounicode{controlCR}{000D} \pdfglyphtounicode{controlDC1}{0011} \pdfglyphtounicode{controlDC2}{0012} \pdfglyphtounicode{controlDC3}{0013} \pdfglyphtounicode{controlDC4}{0014} \pdfglyphtounicode{controlDEL}{007F} \pdfglyphtounicode{controlDLE}{0010} \pdfglyphtounicode{controlEM}{0019} \pdfglyphtounicode{controlENQ}{0005} \pdfglyphtounicode{controlEOT}{0004} \pdfglyphtounicode{controlESC}{001B} \pdfglyphtounicode{controlETB}{0017} \pdfglyphtounicode{controlETX}{0003} \pdfglyphtounicode{controlFF}{000C} \pdfglyphtounicode{controlFS}{001C} \pdfglyphtounicode{controlGS}{001D} \pdfglyphtounicode{controlHT}{0009} \pdfglyphtounicode{controlLF}{000A} \pdfglyphtounicode{controlNAK}{0015} \pdfglyphtounicode{controlRS}{001E} \pdfglyphtounicode{controlSI}{000F} \pdfglyphtounicode{controlSO}{000E} \pdfglyphtounicode{controlSOT}{0002} \pdfglyphtounicode{controlSTX}{0001} \pdfglyphtounicode{controlSUB}{001A} \pdfglyphtounicode{controlSYN}{0016} \pdfglyphtounicode{controlUS}{001F} \pdfglyphtounicode{controlVT}{000B} \pdfglyphtounicode{coproduct}{2A3F} \pdfglyphtounicode{copyright}{00A9} \pdfglyphtounicode{copyrightsans}{00A9} \pdfglyphtounicode{copyrightserif}{00A9} \pdfglyphtounicode{cornerbracketleft}{300C} \pdfglyphtounicode{cornerbracketlefthalfwidth}{FF62} \pdfglyphtounicode{cornerbracketleftvertical}{FE41} \pdfglyphtounicode{cornerbracketright}{300D} \pdfglyphtounicode{cornerbracketrighthalfwidth}{FF63} \pdfglyphtounicode{cornerbracketrightvertical}{FE42} \pdfglyphtounicode{corporationsquare}{337F} \pdfglyphtounicode{cosquare}{33C7} \pdfglyphtounicode{coverkgsquare}{33C6} \pdfglyphtounicode{cparen}{249E} \pdfglyphtounicode{cruzeiro}{20A2} \pdfglyphtounicode{cstretched}{0297} \pdfglyphtounicode{ct}{0063 0074} \pdfglyphtounicode{curlyand}{22CF} \pdfglyphtounicode{curlyleft}{21AB} \pdfglyphtounicode{curlyor}{22CE} \pdfglyphtounicode{curlyright}{21AC} \pdfglyphtounicode{currency}{00A4} \pdfglyphtounicode{cwm}{200C} \pdfglyphtounicode{cyrBreve}{02D8} \pdfglyphtounicode{cyrFlex}{00A0 0311} \pdfglyphtounicode{cyrbreve}{02D8} \pdfglyphtounicode{cyrflex}{00A0 0311} \pdfglyphtounicode{d}{0064} \pdfglyphtounicode{daarmenian}{0564} \pdfglyphtounicode{dabengali}{09A6} \pdfglyphtounicode{dadarabic}{0636} \pdfglyphtounicode{dadeva}{0926} \pdfglyphtounicode{dadfinalarabic}{FEBE} \pdfglyphtounicode{dadinitialarabic}{FEBF} \pdfglyphtounicode{dadmedialarabic}{FEC0} \pdfglyphtounicode{dagesh}{05BC} \pdfglyphtounicode{dageshhebrew}{05BC} \pdfglyphtounicode{dagger}{2020} \pdfglyphtounicode{daggerdbl}{2021} \pdfglyphtounicode{dagujarati}{0AA6} \pdfglyphtounicode{dagurmukhi}{0A26} \pdfglyphtounicode{dahiragana}{3060} \pdfglyphtounicode{dakatakana}{30C0} \pdfglyphtounicode{dalarabic}{062F} \pdfglyphtounicode{dalet}{05D3} \pdfglyphtounicode{daletdagesh}{FB33} \pdfglyphtounicode{daletdageshhebrew}{FB33} \pdfglyphtounicode{daleth}{2138} \pdfglyphtounicode{dalethatafpatah}{05D3 05B2} \pdfglyphtounicode{dalethatafpatahhebrew}{05D3 05B2} \pdfglyphtounicode{dalethatafsegol}{05D3 05B1} \pdfglyphtounicode{dalethatafsegolhebrew}{05D3 05B1} \pdfglyphtounicode{dalethebrew}{05D3} \pdfglyphtounicode{dalethiriq}{05D3 05B4} \pdfglyphtounicode{dalethiriqhebrew}{05D3 05B4} \pdfglyphtounicode{daletholam}{05D3 05B9} \pdfglyphtounicode{daletholamhebrew}{05D3 05B9} \pdfglyphtounicode{daletpatah}{05D3 05B7} \pdfglyphtounicode{daletpatahhebrew}{05D3 05B7} \pdfglyphtounicode{daletqamats}{05D3 05B8} \pdfglyphtounicode{daletqamatshebrew}{05D3 05B8} \pdfglyphtounicode{daletqubuts}{05D3 05BB} \pdfglyphtounicode{daletqubutshebrew}{05D3 05BB} \pdfglyphtounicode{daletsegol}{05D3 05B6} \pdfglyphtounicode{daletsegolhebrew}{05D3 05B6} \pdfglyphtounicode{daletsheva}{05D3 05B0} \pdfglyphtounicode{daletshevahebrew}{05D3 05B0} \pdfglyphtounicode{dalettsere}{05D3 05B5} \pdfglyphtounicode{dalettserehebrew}{05D3 05B5} \pdfglyphtounicode{dalfinalarabic}{FEAA} \pdfglyphtounicode{dammaarabic}{064F} \pdfglyphtounicode{dammalowarabic}{064F} \pdfglyphtounicode{dammatanaltonearabic}{064C} \pdfglyphtounicode{dammatanarabic}{064C} \pdfglyphtounicode{danda}{0964} \pdfglyphtounicode{dargahebrew}{05A7} \pdfglyphtounicode{dargalefthebrew}{05A7} \pdfglyphtounicode{dasiapneumatacyrilliccmb}{0485} \pdfglyphtounicode{dbar}{0111} \pdfglyphtounicode{dblGrave}{00A0 030F} \pdfglyphtounicode{dblanglebracketleft}{300A} \pdfglyphtounicode{dblanglebracketleftvertical}{FE3D} \pdfglyphtounicode{dblanglebracketright}{300B} \pdfglyphtounicode{dblanglebracketrightvertical}{FE3E} \pdfglyphtounicode{dblarchinvertedbelowcmb}{032B} \pdfglyphtounicode{dblarrowdwn}{21CA} \pdfglyphtounicode{dblarrowheadleft}{219E} \pdfglyphtounicode{dblarrowheadright}{21A0} \pdfglyphtounicode{dblarrowleft}{21D4} \pdfglyphtounicode{dblarrowright}{21D2} \pdfglyphtounicode{dblarrowup}{21C8} \pdfglyphtounicode{dblbracketleft}{27E6} \pdfglyphtounicode{dblbracketright}{27E7} \pdfglyphtounicode{dbldanda}{0965} \pdfglyphtounicode{dblgrave}{00A0 030F} \pdfglyphtounicode{dblgravecmb}{030F} \pdfglyphtounicode{dblintegral}{222C} \pdfglyphtounicode{dbllowline}{2017} \pdfglyphtounicode{dbllowlinecmb}{0333} \pdfglyphtounicode{dbloverlinecmb}{033F} \pdfglyphtounicode{dblprimemod}{02BA} \pdfglyphtounicode{dblverticalbar}{2016} \pdfglyphtounicode{dblverticallineabovecmb}{030E} \pdfglyphtounicode{dbopomofo}{3109} \pdfglyphtounicode{dbsquare}{33C8} \pdfglyphtounicode{dcaron}{010F} \pdfglyphtounicode{dcedilla}{1E11} \pdfglyphtounicode{dcircle}{24D3} \pdfglyphtounicode{dcircumflexbelow}{1E13} \pdfglyphtounicode{dcroat}{0111} \pdfglyphtounicode{ddabengali}{09A1} \pdfglyphtounicode{ddadeva}{0921} \pdfglyphtounicode{ddagujarati}{0AA1} \pdfglyphtounicode{ddagurmukhi}{0A21} \pdfglyphtounicode{ddalarabic}{0688} \pdfglyphtounicode{ddalfinalarabic}{FB89} \pdfglyphtounicode{dddhadeva}{095C} \pdfglyphtounicode{ddhabengali}{09A2} \pdfglyphtounicode{ddhadeva}{0922} \pdfglyphtounicode{ddhagujarati}{0AA2} \pdfglyphtounicode{ddhagurmukhi}{0A22} \pdfglyphtounicode{ddotaccent}{1E0B} \pdfglyphtounicode{ddotbelow}{1E0D} \pdfglyphtounicode{decimalseparatorarabic}{066B} \pdfglyphtounicode{decimalseparatorpersian}{066B} \pdfglyphtounicode{decyrillic}{0434} \pdfglyphtounicode{defines}{225C} \pdfglyphtounicode{degree}{00B0} \pdfglyphtounicode{dehihebrew}{05AD} \pdfglyphtounicode{dehiragana}{3067} \pdfglyphtounicode{deicoptic}{03EF} \pdfglyphtounicode{dekatakana}{30C7} \pdfglyphtounicode{deleteleft}{232B} \pdfglyphtounicode{deleteright}{2326} \pdfglyphtounicode{delta}{03B4} \pdfglyphtounicode{deltaturned}{018D} \pdfglyphtounicode{denominatorminusonenumeratorbengali}{09F8} \pdfglyphtounicode{dezh}{02A4} \pdfglyphtounicode{dhabengali}{09A7} \pdfglyphtounicode{dhadeva}{0927} \pdfglyphtounicode{dhagujarati}{0AA7} \pdfglyphtounicode{dhagurmukhi}{0A27} \pdfglyphtounicode{dhook}{0257} \pdfglyphtounicode{dialytikatonos}{0385} \pdfglyphtounicode{dialytikatonoscmb}{0344} \pdfglyphtounicode{diamond}{2666} \pdfglyphtounicode{diamondmath}{22C4} \pdfglyphtounicode{diamondsolid}{2666} \pdfglyphtounicode{diamondsuitwhite}{2662} \pdfglyphtounicode{dieresis}{00A8} \pdfglyphtounicode{dieresisacute}{00A0 0308 0301} \pdfglyphtounicode{dieresisbelowcmb}{0324} \pdfglyphtounicode{dieresiscmb}{0308} \pdfglyphtounicode{dieresisgrave}{00A0 0308 0300} \pdfglyphtounicode{dieresistonos}{0385} \pdfglyphtounicode{difference}{224F} \pdfglyphtounicode{dihiragana}{3062} \pdfglyphtounicode{dikatakana}{30C2} \pdfglyphtounicode{dittomark}{3003} \pdfglyphtounicode{divide}{00F7} \pdfglyphtounicode{dividemultiply}{22C7} \pdfglyphtounicode{divides}{2223} \pdfglyphtounicode{divisionslash}{2215} \pdfglyphtounicode{djecyrillic}{0452} \pdfglyphtounicode{dkshade}{2593} \pdfglyphtounicode{dlinebelow}{1E0F} \pdfglyphtounicode{dlsquare}{3397} \pdfglyphtounicode{dmacron}{0111} \pdfglyphtounicode{dmonospace}{FF44} \pdfglyphtounicode{dnblock}{2584} \pdfglyphtounicode{dochadathai}{0E0E} \pdfglyphtounicode{dodekthai}{0E14} \pdfglyphtounicode{dohiragana}{3069} \pdfglyphtounicode{dokatakana}{30C9} \pdfglyphtounicode{dollar}{0024} \pdfglyphtounicode{dollarinferior}{0024} \pdfglyphtounicode{dollarmonospace}{FF04} \pdfglyphtounicode{dollaroldstyle}{0024} \pdfglyphtounicode{dollarsmall}{FE69} \pdfglyphtounicode{dollarsuperior}{0024} \pdfglyphtounicode{dong}{20AB} \pdfglyphtounicode{dorusquare}{3326} \pdfglyphtounicode{dotaccent}{02D9} \pdfglyphtounicode{dotaccentcmb}{0307} \pdfglyphtounicode{dotbelowcmb}{0323} \pdfglyphtounicode{dotbelowcomb}{0323} \pdfglyphtounicode{dotkatakana}{30FB} \pdfglyphtounicode{dotlessi}{0131} \pdfglyphtounicode{dotlessj}{0237} \pdfglyphtounicode{dotlessjstrokehook}{0284} \pdfglyphtounicode{dotmath}{22C5} \pdfglyphtounicode{dotplus}{2214} \pdfglyphtounicode{dottedcircle}{25CC} \pdfglyphtounicode{doubleyodpatah}{FB1F} \pdfglyphtounicode{doubleyodpatahhebrew}{FB1F} \pdfglyphtounicode{downfall}{22CE} \pdfglyphtounicode{downslope}{29F9} \pdfglyphtounicode{downtackbelowcmb}{031E} \pdfglyphtounicode{downtackmod}{02D5} \pdfglyphtounicode{dparen}{249F} \pdfglyphtounicode{dsuperior}{0064} \pdfglyphtounicode{dtail}{0256} \pdfglyphtounicode{dtopbar}{018C} \pdfglyphtounicode{duhiragana}{3065} \pdfglyphtounicode{dukatakana}{30C5} \pdfglyphtounicode{dz}{01F3} \pdfglyphtounicode{dzaltone}{02A3} \pdfglyphtounicode{dzcaron}{01C6} \pdfglyphtounicode{dzcurl}{02A5} \pdfglyphtounicode{dzeabkhasiancyrillic}{04E1} \pdfglyphtounicode{dzecyrillic}{0455} \pdfglyphtounicode{dzhecyrillic}{045F} \pdfglyphtounicode{e}{0065} \pdfglyphtounicode{eacute}{00E9} \pdfglyphtounicode{earth}{2641} \pdfglyphtounicode{ebengali}{098F} \pdfglyphtounicode{ebopomofo}{311C} \pdfglyphtounicode{ebreve}{0115} \pdfglyphtounicode{ecandradeva}{090D} \pdfglyphtounicode{ecandragujarati}{0A8D} \pdfglyphtounicode{ecandravowelsigndeva}{0945} \pdfglyphtounicode{ecandravowelsigngujarati}{0AC5} \pdfglyphtounicode{ecaron}{011B} \pdfglyphtounicode{ecedillabreve}{1E1D} \pdfglyphtounicode{echarmenian}{0565} \pdfglyphtounicode{echyiwnarmenian}{0587} \pdfglyphtounicode{ecircle}{24D4} \pdfglyphtounicode{ecircumflex}{00EA} \pdfglyphtounicode{ecircumflexacute}{1EBF} \pdfglyphtounicode{ecircumflexbelow}{1E19} \pdfglyphtounicode{ecircumflexdotbelow}{1EC7} \pdfglyphtounicode{ecircumflexgrave}{1EC1} \pdfglyphtounicode{ecircumflexhookabove}{1EC3} \pdfglyphtounicode{ecircumflextilde}{1EC5} \pdfglyphtounicode{ecyrillic}{0454} \pdfglyphtounicode{edblgrave}{0205} \pdfglyphtounicode{edeva}{090F} \pdfglyphtounicode{edieresis}{00EB} \pdfglyphtounicode{edot}{0117} \pdfglyphtounicode{edotaccent}{0117} \pdfglyphtounicode{edotbelow}{1EB9} \pdfglyphtounicode{eegurmukhi}{0A0F} \pdfglyphtounicode{eematragurmukhi}{0A47} \pdfglyphtounicode{efcyrillic}{0444} \pdfglyphtounicode{egrave}{00E8} \pdfglyphtounicode{egujarati}{0A8F} \pdfglyphtounicode{eharmenian}{0567} \pdfglyphtounicode{ehbopomofo}{311D} \pdfglyphtounicode{ehiragana}{3048} \pdfglyphtounicode{ehookabove}{1EBB} \pdfglyphtounicode{eibopomofo}{311F} \pdfglyphtounicode{eight}{0038} \pdfglyphtounicode{eightarabic}{0668} \pdfglyphtounicode{eightbengali}{09EE} \pdfglyphtounicode{eightcircle}{2467} \pdfglyphtounicode{eightcircleinversesansserif}{2791} \pdfglyphtounicode{eightdeva}{096E} \pdfglyphtounicode{eighteencircle}{2471} \pdfglyphtounicode{eighteenparen}{2485} \pdfglyphtounicode{eighteenperiod}{2499} \pdfglyphtounicode{eightgujarati}{0AEE} \pdfglyphtounicode{eightgurmukhi}{0A6E} \pdfglyphtounicode{eighthackarabic}{0668} \pdfglyphtounicode{eighthangzhou}{3028} \pdfglyphtounicode{eighthnotebeamed}{266B} \pdfglyphtounicode{eightideographicparen}{3227} \pdfglyphtounicode{eightinferior}{2088} \pdfglyphtounicode{eightmonospace}{FF18} \pdfglyphtounicode{eightoldstyle}{0038} \pdfglyphtounicode{eightparen}{247B} \pdfglyphtounicode{eightperiod}{248F} \pdfglyphtounicode{eightpersian}{06F8} \pdfglyphtounicode{eightroman}{2177} \pdfglyphtounicode{eightsuperior}{2078} \pdfglyphtounicode{eightthai}{0E58} \pdfglyphtounicode{einvertedbreve}{0207} \pdfglyphtounicode{eiotifiedcyrillic}{0465} \pdfglyphtounicode{ekatakana}{30A8} \pdfglyphtounicode{ekatakanahalfwidth}{FF74} \pdfglyphtounicode{ekonkargurmukhi}{0A74} \pdfglyphtounicode{ekorean}{3154} \pdfglyphtounicode{elcyrillic}{043B} \pdfglyphtounicode{element}{2208} \pdfglyphtounicode{elevencircle}{246A} \pdfglyphtounicode{elevenparen}{247E} \pdfglyphtounicode{elevenperiod}{2492} \pdfglyphtounicode{elevenroman}{217A} \pdfglyphtounicode{ellipsis}{2026} \pdfglyphtounicode{ellipsisvertical}{22EE} \pdfglyphtounicode{emacron}{0113} \pdfglyphtounicode{emacronacute}{1E17} \pdfglyphtounicode{emacrongrave}{1E15} \pdfglyphtounicode{emcyrillic}{043C} \pdfglyphtounicode{emdash}{2014} \pdfglyphtounicode{emdashvertical}{FE31} \pdfglyphtounicode{emonospace}{FF45} \pdfglyphtounicode{emphasismarkarmenian}{055B} \pdfglyphtounicode{emptyset}{2205} \pdfglyphtounicode{enbopomofo}{3123} \pdfglyphtounicode{encyrillic}{043D} \pdfglyphtounicode{endash}{2013} \pdfglyphtounicode{endashvertical}{FE32} \pdfglyphtounicode{endescendercyrillic}{04A3} \pdfglyphtounicode{eng}{014B} \pdfglyphtounicode{engbopomofo}{3125} \pdfglyphtounicode{enghecyrillic}{04A5} \pdfglyphtounicode{enhookcyrillic}{04C8} \pdfglyphtounicode{enspace}{2002} \pdfglyphtounicode{eogonek}{0119} \pdfglyphtounicode{eokorean}{3153} \pdfglyphtounicode{eopen}{025B} \pdfglyphtounicode{eopenclosed}{029A} \pdfglyphtounicode{eopenreversed}{025C} \pdfglyphtounicode{eopenreversedclosed}{025E} \pdfglyphtounicode{eopenreversedhook}{025D} \pdfglyphtounicode{eparen}{24A0} \pdfglyphtounicode{epsilon}{03B5} \pdfglyphtounicode{epsilon1}{03F5} \pdfglyphtounicode{epsiloninv}{03F6} \pdfglyphtounicode{epsilontonos}{03AD} \pdfglyphtounicode{equal}{003D} \pdfglyphtounicode{equaldotleftright}{2252} \pdfglyphtounicode{equaldotrightleft}{2253} \pdfglyphtounicode{equalmonospace}{FF1D} \pdfglyphtounicode{equalorfollows}{22DF} \pdfglyphtounicode{equalorgreater}{2A96} \pdfglyphtounicode{equalorless}{2A95} \pdfglyphtounicode{equalorprecedes}{22DE} \pdfglyphtounicode{equalorsimilar}{2242} \pdfglyphtounicode{equalsdots}{2251} \pdfglyphtounicode{equalsmall}{FE66} \pdfglyphtounicode{equalsuperior}{207C} \pdfglyphtounicode{equivalence}{2261} \pdfglyphtounicode{equivasymptotic}{224D} \pdfglyphtounicode{erbopomofo}{3126} \pdfglyphtounicode{ercyrillic}{0440} \pdfglyphtounicode{ereversed}{0258} \pdfglyphtounicode{ereversedcyrillic}{044D} \pdfglyphtounicode{escyrillic}{0441} \pdfglyphtounicode{esdescendercyrillic}{04AB} \pdfglyphtounicode{esh}{0283} \pdfglyphtounicode{eshcurl}{0286} \pdfglyphtounicode{eshortdeva}{090E} \pdfglyphtounicode{eshortvowelsigndeva}{0946} \pdfglyphtounicode{eshreversedloop}{01AA} \pdfglyphtounicode{eshsquatreversed}{0285} \pdfglyphtounicode{esmallhiragana}{3047} \pdfglyphtounicode{esmallkatakana}{30A7} \pdfglyphtounicode{esmallkatakanahalfwidth}{FF6A} \pdfglyphtounicode{estimated}{212E} \pdfglyphtounicode{esuperior}{0065} \pdfglyphtounicode{eta}{03B7} \pdfglyphtounicode{etarmenian}{0568} \pdfglyphtounicode{etatonos}{03AE} \pdfglyphtounicode{eth}{00F0} \pdfglyphtounicode{etilde}{1EBD} \pdfglyphtounicode{etildebelow}{1E1B} \pdfglyphtounicode{etnahtafoukhhebrew}{0591} \pdfglyphtounicode{etnahtafoukhlefthebrew}{0591} \pdfglyphtounicode{etnahtahebrew}{0591} \pdfglyphtounicode{etnahtalefthebrew}{0591} \pdfglyphtounicode{eturned}{01DD} \pdfglyphtounicode{eukorean}{3161} \pdfglyphtounicode{euro}{20AC} \pdfglyphtounicode{evowelsignbengali}{09C7} \pdfglyphtounicode{evowelsigndeva}{0947} \pdfglyphtounicode{evowelsigngujarati}{0AC7} \pdfglyphtounicode{exclam}{0021} \pdfglyphtounicode{exclamarmenian}{055C} \pdfglyphtounicode{exclamdbl}{203C} \pdfglyphtounicode{exclamdown}{00A1} \pdfglyphtounicode{exclamdownsmall}{00A1} \pdfglyphtounicode{exclammonospace}{FF01} \pdfglyphtounicode{exclamsmall}{0021} \pdfglyphtounicode{existential}{2203} \pdfglyphtounicode{ezh}{0292} \pdfglyphtounicode{ezhcaron}{01EF} \pdfglyphtounicode{ezhcurl}{0293} \pdfglyphtounicode{ezhreversed}{01B9} \pdfglyphtounicode{ezhtail}{01BA} \pdfglyphtounicode{f}{0066} \pdfglyphtounicode{fadeva}{095E} \pdfglyphtounicode{fagurmukhi}{0A5E} \pdfglyphtounicode{fahrenheit}{2109} \pdfglyphtounicode{fathaarabic}{064E} \pdfglyphtounicode{fathalowarabic}{064E} \pdfglyphtounicode{fathatanarabic}{064B} \pdfglyphtounicode{fbopomofo}{3108} \pdfglyphtounicode{fcircle}{24D5} \pdfglyphtounicode{fdotaccent}{1E1F} \pdfglyphtounicode{feharabic}{0641} \pdfglyphtounicode{feharmenian}{0586} \pdfglyphtounicode{fehfinalarabic}{FED2} \pdfglyphtounicode{fehinitialarabic}{FED3} \pdfglyphtounicode{fehmedialarabic}{FED4} \pdfglyphtounicode{feicoptic}{03E5} \pdfglyphtounicode{female}{2640} \pdfglyphtounicode{ff}{0066 0066} \pdfglyphtounicode{ffi}{0066 0066 0069} \pdfglyphtounicode{ffl}{0066 0066 006C} \pdfglyphtounicode{fi}{0066 0069} \pdfglyphtounicode{fifteencircle}{246E} \pdfglyphtounicode{fifteenparen}{2482} \pdfglyphtounicode{fifteenperiod}{2496} \pdfglyphtounicode{figuredash}{2012} \pdfglyphtounicode{filledbox}{25A0} \pdfglyphtounicode{filledrect}{25AC} \pdfglyphtounicode{finalkaf}{05DA} \pdfglyphtounicode{finalkafdagesh}{FB3A} \pdfglyphtounicode{finalkafdageshhebrew}{FB3A} \pdfglyphtounicode{finalkafhebrew}{05DA} \pdfglyphtounicode{finalkafqamats}{05DA 05B8} \pdfglyphtounicode{finalkafqamatshebrew}{05DA 05B8} \pdfglyphtounicode{finalkafsheva}{05DA 05B0} \pdfglyphtounicode{finalkafshevahebrew}{05DA 05B0} \pdfglyphtounicode{finalmem}{05DD} \pdfglyphtounicode{finalmemhebrew}{05DD} \pdfglyphtounicode{finalnun}{05DF} \pdfglyphtounicode{finalnunhebrew}{05DF} \pdfglyphtounicode{finalpe}{05E3} \pdfglyphtounicode{finalpehebrew}{05E3} \pdfglyphtounicode{finaltsadi}{05E5} \pdfglyphtounicode{finaltsadihebrew}{05E5} \pdfglyphtounicode{firsttonechinese}{02C9} \pdfglyphtounicode{fisheye}{25C9} \pdfglyphtounicode{fitacyrillic}{0473} \pdfglyphtounicode{five}{0035} \pdfglyphtounicode{fivearabic}{0665} \pdfglyphtounicode{fivebengali}{09EB} \pdfglyphtounicode{fivecircle}{2464} \pdfglyphtounicode{fivecircleinversesansserif}{278E} \pdfglyphtounicode{fivedeva}{096B} \pdfglyphtounicode{fiveeighths}{215D} \pdfglyphtounicode{fivegujarati}{0AEB} \pdfglyphtounicode{fivegurmukhi}{0A6B} \pdfglyphtounicode{fivehackarabic}{0665} \pdfglyphtounicode{fivehangzhou}{3025} \pdfglyphtounicode{fiveideographicparen}{3224} \pdfglyphtounicode{fiveinferior}{2085} \pdfglyphtounicode{fivemonospace}{FF15} \pdfglyphtounicode{fiveoldstyle}{0035} \pdfglyphtounicode{fiveparen}{2478} \pdfglyphtounicode{fiveperiod}{248C} \pdfglyphtounicode{fivepersian}{06F5} \pdfglyphtounicode{fiveroman}{2174} \pdfglyphtounicode{fivesuperior}{2075} \pdfglyphtounicode{fivethai}{0E55} \pdfglyphtounicode{fl}{0066 006C} \pdfglyphtounicode{flat}{266D} \pdfglyphtounicode{floorleft}{230A} \pdfglyphtounicode{floorright}{230B} \pdfglyphtounicode{florin}{0192} \pdfglyphtounicode{fmonospace}{FF46} \pdfglyphtounicode{fmsquare}{3399} \pdfglyphtounicode{fofanthai}{0E1F} \pdfglyphtounicode{fofathai}{0E1D} \pdfglyphtounicode{follownotdbleqv}{2ABA} \pdfglyphtounicode{follownotslnteql}{2AB6} \pdfglyphtounicode{followornoteqvlnt}{22E9} \pdfglyphtounicode{follows}{227B} \pdfglyphtounicode{followsequal}{2AB0} \pdfglyphtounicode{followsorcurly}{227D} \pdfglyphtounicode{followsorequal}{227F} \pdfglyphtounicode{fongmanthai}{0E4F} \pdfglyphtounicode{forall}{2200} \pdfglyphtounicode{forces}{22A9} \pdfglyphtounicode{forcesbar}{22AA} \pdfglyphtounicode{fork}{22D4} \pdfglyphtounicode{four}{0034} \pdfglyphtounicode{fourarabic}{0664} \pdfglyphtounicode{fourbengali}{09EA} \pdfglyphtounicode{fourcircle}{2463} \pdfglyphtounicode{fourcircleinversesansserif}{278D} \pdfglyphtounicode{fourdeva}{096A} \pdfglyphtounicode{fourgujarati}{0AEA} \pdfglyphtounicode{fourgurmukhi}{0A6A} \pdfglyphtounicode{fourhackarabic}{0664} \pdfglyphtounicode{fourhangzhou}{3024} \pdfglyphtounicode{fourideographicparen}{3223} \pdfglyphtounicode{fourinferior}{2084} \pdfglyphtounicode{fourmonospace}{FF14} \pdfglyphtounicode{fournumeratorbengali}{09F7} \pdfglyphtounicode{fouroldstyle}{0034} \pdfglyphtounicode{fourparen}{2477} \pdfglyphtounicode{fourperiod}{248B} \pdfglyphtounicode{fourpersian}{06F4} \pdfglyphtounicode{fourroman}{2173} \pdfglyphtounicode{foursuperior}{2074} \pdfglyphtounicode{fourteencircle}{246D} \pdfglyphtounicode{fourteenparen}{2481} \pdfglyphtounicode{fourteenperiod}{2495} \pdfglyphtounicode{fourthai}{0E54} \pdfglyphtounicode{fourthtonechinese}{02CB} \pdfglyphtounicode{fparen}{24A1} \pdfglyphtounicode{fraction}{2044} \pdfglyphtounicode{franc}{20A3} \pdfglyphtounicode{frown}{2322} \pdfglyphtounicode{g}{0067} \pdfglyphtounicode{gabengali}{0997} \pdfglyphtounicode{gacute}{01F5} \pdfglyphtounicode{gadeva}{0917} \pdfglyphtounicode{gafarabic}{06AF} \pdfglyphtounicode{gaffinalarabic}{FB93} \pdfglyphtounicode{gafinitialarabic}{FB94} \pdfglyphtounicode{gafmedialarabic}{FB95} \pdfglyphtounicode{gagujarati}{0A97} \pdfglyphtounicode{gagurmukhi}{0A17} \pdfglyphtounicode{gahiragana}{304C} \pdfglyphtounicode{gakatakana}{30AC} \pdfglyphtounicode{gamma}{03B3} \pdfglyphtounicode{gammalatinsmall}{0263} \pdfglyphtounicode{gammasuperior}{02E0} \pdfglyphtounicode{gangiacoptic}{03EB} \pdfglyphtounicode{gbopomofo}{310D} \pdfglyphtounicode{gbreve}{011F} \pdfglyphtounicode{gcaron}{01E7} \pdfglyphtounicode{gcedilla}{0123} \pdfglyphtounicode{gcircle}{24D6} \pdfglyphtounicode{gcircumflex}{011D} \pdfglyphtounicode{gcommaaccent}{0123} \pdfglyphtounicode{gdot}{0121} \pdfglyphtounicode{gdotaccent}{0121} \pdfglyphtounicode{gecyrillic}{0433} \pdfglyphtounicode{gehiragana}{3052} \pdfglyphtounicode{gekatakana}{30B2} \pdfglyphtounicode{geomequivalent}{224E} \pdfglyphtounicode{geometricallyequal}{2251} \pdfglyphtounicode{gereshaccenthebrew}{059C} \pdfglyphtounicode{gereshhebrew}{05F3} \pdfglyphtounicode{gereshmuqdamhebrew}{059D} \pdfglyphtounicode{germandbls}{00DF} \pdfglyphtounicode{gershayimaccenthebrew}{059E} \pdfglyphtounicode{gershayimhebrew}{05F4} \pdfglyphtounicode{getamark}{3013} \pdfglyphtounicode{ghabengali}{0998} \pdfglyphtounicode{ghadarmenian}{0572} \pdfglyphtounicode{ghadeva}{0918} \pdfglyphtounicode{ghagujarati}{0A98} \pdfglyphtounicode{ghagurmukhi}{0A18} \pdfglyphtounicode{ghainarabic}{063A} \pdfglyphtounicode{ghainfinalarabic}{FECE} \pdfglyphtounicode{ghaininitialarabic}{FECF} \pdfglyphtounicode{ghainmedialarabic}{FED0} \pdfglyphtounicode{ghemiddlehookcyrillic}{0495} \pdfglyphtounicode{ghestrokecyrillic}{0493} \pdfglyphtounicode{gheupturncyrillic}{0491} \pdfglyphtounicode{ghhadeva}{095A} \pdfglyphtounicode{ghhagurmukhi}{0A5A} \pdfglyphtounicode{ghook}{0260} \pdfglyphtounicode{ghzsquare}{3393} \pdfglyphtounicode{gihiragana}{304E} \pdfglyphtounicode{gikatakana}{30AE} \pdfglyphtounicode{gimarmenian}{0563} \pdfglyphtounicode{gimel}{05D2} \pdfglyphtounicode{gimeldagesh}{FB32} \pdfglyphtounicode{gimeldageshhebrew}{FB32} \pdfglyphtounicode{gimelhebrew}{05D2} \pdfglyphtounicode{gjecyrillic}{0453} \pdfglyphtounicode{glottalinvertedstroke}{01BE} \pdfglyphtounicode{glottalstop}{0294} \pdfglyphtounicode{glottalstopinverted}{0296} \pdfglyphtounicode{glottalstopmod}{02C0} \pdfglyphtounicode{glottalstopreversed}{0295} \pdfglyphtounicode{glottalstopreversedmod}{02C1} \pdfglyphtounicode{glottalstopreversedsuperior}{02E4} \pdfglyphtounicode{glottalstopstroke}{02A1} \pdfglyphtounicode{glottalstopstrokereversed}{02A2} \pdfglyphtounicode{gmacron}{1E21} \pdfglyphtounicode{gmonospace}{FF47} \pdfglyphtounicode{gohiragana}{3054} \pdfglyphtounicode{gokatakana}{30B4} \pdfglyphtounicode{gparen}{24A2} \pdfglyphtounicode{gpasquare}{33AC} \pdfglyphtounicode{gradient}{2207} \pdfglyphtounicode{grave}{0060} \pdfglyphtounicode{gravebelowcmb}{0316} \pdfglyphtounicode{gravecmb}{0300} \pdfglyphtounicode{gravecomb}{0300} \pdfglyphtounicode{gravedeva}{0953} \pdfglyphtounicode{gravelowmod}{02CE} \pdfglyphtounicode{gravemonospace}{FF40} \pdfglyphtounicode{gravetonecmb}{0340} \pdfglyphtounicode{greater}{003E} \pdfglyphtounicode{greaterdbleqlless}{2A8C} \pdfglyphtounicode{greaterdblequal}{2267} \pdfglyphtounicode{greaterdot}{22D7} \pdfglyphtounicode{greaterequal}{2265} \pdfglyphtounicode{greaterequalorless}{22DB} \pdfglyphtounicode{greaterlessequal}{22DB} \pdfglyphtounicode{greatermonospace}{FF1E} \pdfglyphtounicode{greatermuch}{226B} \pdfglyphtounicode{greaternotdblequal}{2A8A} \pdfglyphtounicode{greaternotequal}{2A88} \pdfglyphtounicode{greaterorapproxeql}{2A86} \pdfglyphtounicode{greaterorequalslant}{2A7E} \pdfglyphtounicode{greaterorequivalent}{2273} \pdfglyphtounicode{greaterorless}{2277} \pdfglyphtounicode{greaterornotdbleql}{2269} \pdfglyphtounicode{greaterornotequal}{2269} \pdfglyphtounicode{greaterorsimilar}{2273} \pdfglyphtounicode{greateroverequal}{2267} \pdfglyphtounicode{greatersmall}{FE65} \pdfglyphtounicode{gscript}{0261} \pdfglyphtounicode{gstroke}{01E5} \pdfglyphtounicode{guhiragana}{3050} \pdfglyphtounicode{guillemotleft}{00AB} \pdfglyphtounicode{guillemotright}{00BB} \pdfglyphtounicode{guilsinglleft}{2039} \pdfglyphtounicode{guilsinglright}{203A} \pdfglyphtounicode{gukatakana}{30B0} \pdfglyphtounicode{guramusquare}{3318} \pdfglyphtounicode{gysquare}{33C9} \pdfglyphtounicode{h}{0068} \pdfglyphtounicode{haabkhasiancyrillic}{04A9} \pdfglyphtounicode{haaltonearabic}{06C1} \pdfglyphtounicode{habengali}{09B9} \pdfglyphtounicode{hadescendercyrillic}{04B3} \pdfglyphtounicode{hadeva}{0939} \pdfglyphtounicode{hagujarati}{0AB9} \pdfglyphtounicode{hagurmukhi}{0A39} \pdfglyphtounicode{haharabic}{062D} \pdfglyphtounicode{hahfinalarabic}{FEA2} \pdfglyphtounicode{hahinitialarabic}{FEA3} \pdfglyphtounicode{hahiragana}{306F} \pdfglyphtounicode{hahmedialarabic}{FEA4} \pdfglyphtounicode{haitusquare}{332A} \pdfglyphtounicode{hakatakana}{30CF} \pdfglyphtounicode{hakatakanahalfwidth}{FF8A} \pdfglyphtounicode{halantgurmukhi}{0A4D} \pdfglyphtounicode{hamzaarabic}{0621} \pdfglyphtounicode{hamzadammaarabic}{0621 064F} \pdfglyphtounicode{hamzadammatanarabic}{0621 064C} \pdfglyphtounicode{hamzafathaarabic}{0621 064E} \pdfglyphtounicode{hamzafathatanarabic}{0621 064B} \pdfglyphtounicode{hamzalowarabic}{0621} \pdfglyphtounicode{hamzalowkasraarabic}{0621 0650} \pdfglyphtounicode{hamzalowkasratanarabic}{0621 064D} \pdfglyphtounicode{hamzasukunarabic}{0621 0652} \pdfglyphtounicode{hangulfiller}{3164} \pdfglyphtounicode{hardsigncyrillic}{044A} \pdfglyphtounicode{harpoondownleft}{21C3} \pdfglyphtounicode{harpoondownright}{21C2} \pdfglyphtounicode{harpoonleftbarbup}{21BC} \pdfglyphtounicode{harpoonleftright}{21CC} \pdfglyphtounicode{harpoonrightbarbup}{21C0} \pdfglyphtounicode{harpoonrightleft}{21CB} \pdfglyphtounicode{harpoonupleft}{21BF} \pdfglyphtounicode{harpoonupright}{21BE} \pdfglyphtounicode{hasquare}{33CA} \pdfglyphtounicode{hatafpatah}{05B2} \pdfglyphtounicode{hatafpatah16}{05B2} \pdfglyphtounicode{hatafpatah23}{05B2} \pdfglyphtounicode{hatafpatah2f}{05B2} \pdfglyphtounicode{hatafpatahhebrew}{05B2} \pdfglyphtounicode{hatafpatahnarrowhebrew}{05B2} \pdfglyphtounicode{hatafpatahquarterhebrew}{05B2} \pdfglyphtounicode{hatafpatahwidehebrew}{05B2} \pdfglyphtounicode{hatafqamats}{05B3} \pdfglyphtounicode{hatafqamats1b}{05B3} \pdfglyphtounicode{hatafqamats28}{05B3} \pdfglyphtounicode{hatafqamats34}{05B3} \pdfglyphtounicode{hatafqamatshebrew}{05B3} \pdfglyphtounicode{hatafqamatsnarrowhebrew}{05B3} \pdfglyphtounicode{hatafqamatsquarterhebrew}{05B3} \pdfglyphtounicode{hatafqamatswidehebrew}{05B3} \pdfglyphtounicode{hatafsegol}{05B1} \pdfglyphtounicode{hatafsegol17}{05B1} \pdfglyphtounicode{hatafsegol24}{05B1} \pdfglyphtounicode{hatafsegol30}{05B1} \pdfglyphtounicode{hatafsegolhebrew}{05B1} \pdfglyphtounicode{hatafsegolnarrowhebrew}{05B1} \pdfglyphtounicode{hatafsegolquarterhebrew}{05B1} \pdfglyphtounicode{hatafsegolwidehebrew}{05B1} \pdfglyphtounicode{hbar}{0127} \pdfglyphtounicode{hbopomofo}{310F} \pdfglyphtounicode{hbrevebelow}{1E2B} \pdfglyphtounicode{hcedilla}{1E29} \pdfglyphtounicode{hcircle}{24D7} \pdfglyphtounicode{hcircumflex}{0125} \pdfglyphtounicode{hdieresis}{1E27} \pdfglyphtounicode{hdotaccent}{1E23} \pdfglyphtounicode{hdotbelow}{1E25} \pdfglyphtounicode{he}{05D4} \pdfglyphtounicode{heart}{2665} \pdfglyphtounicode{heartsuitblack}{2665} \pdfglyphtounicode{heartsuitwhite}{2661} \pdfglyphtounicode{hedagesh}{FB34} \pdfglyphtounicode{hedageshhebrew}{FB34} \pdfglyphtounicode{hehaltonearabic}{06C1} \pdfglyphtounicode{heharabic}{0647} \pdfglyphtounicode{hehebrew}{05D4} \pdfglyphtounicode{hehfinalaltonearabic}{FBA7} \pdfglyphtounicode{hehfinalalttwoarabic}{FEEA} \pdfglyphtounicode{hehfinalarabic}{FEEA} \pdfglyphtounicode{hehhamzaabovefinalarabic}{FBA5} \pdfglyphtounicode{hehhamzaaboveisolatedarabic}{FBA4} \pdfglyphtounicode{hehinitialaltonearabic}{FBA8} \pdfglyphtounicode{hehinitialarabic}{FEEB} \pdfglyphtounicode{hehiragana}{3078} \pdfglyphtounicode{hehmedialaltonearabic}{FBA9} \pdfglyphtounicode{hehmedialarabic}{FEEC} \pdfglyphtounicode{heiseierasquare}{337B} \pdfglyphtounicode{hekatakana}{30D8} \pdfglyphtounicode{hekatakanahalfwidth}{FF8D} \pdfglyphtounicode{hekutaarusquare}{3336} \pdfglyphtounicode{henghook}{0267} \pdfglyphtounicode{herutusquare}{3339} \pdfglyphtounicode{het}{05D7} \pdfglyphtounicode{hethebrew}{05D7} \pdfglyphtounicode{hhook}{0266} \pdfglyphtounicode{hhooksuperior}{02B1} \pdfglyphtounicode{hieuhacirclekorean}{327B} \pdfglyphtounicode{hieuhaparenkorean}{321B} \pdfglyphtounicode{hieuhcirclekorean}{326D} \pdfglyphtounicode{hieuhkorean}{314E} \pdfglyphtounicode{hieuhparenkorean}{320D} \pdfglyphtounicode{hihiragana}{3072} \pdfglyphtounicode{hikatakana}{30D2} \pdfglyphtounicode{hikatakanahalfwidth}{FF8B} \pdfglyphtounicode{hiriq}{05B4} \pdfglyphtounicode{hiriq14}{05B4} \pdfglyphtounicode{hiriq21}{05B4} \pdfglyphtounicode{hiriq2d}{05B4} \pdfglyphtounicode{hiriqhebrew}{05B4} \pdfglyphtounicode{hiriqnarrowhebrew}{05B4} \pdfglyphtounicode{hiriqquarterhebrew}{05B4} \pdfglyphtounicode{hiriqwidehebrew}{05B4} \pdfglyphtounicode{hlinebelow}{1E96} \pdfglyphtounicode{hmonospace}{FF48} \pdfglyphtounicode{hoarmenian}{0570} \pdfglyphtounicode{hohipthai}{0E2B} \pdfglyphtounicode{hohiragana}{307B} \pdfglyphtounicode{hokatakana}{30DB} \pdfglyphtounicode{hokatakanahalfwidth}{FF8E} \pdfglyphtounicode{holam}{05B9} \pdfglyphtounicode{holam19}{05B9} \pdfglyphtounicode{holam26}{05B9} \pdfglyphtounicode{holam32}{05B9} \pdfglyphtounicode{holamhebrew}{05B9} \pdfglyphtounicode{holamnarrowhebrew}{05B9} \pdfglyphtounicode{holamquarterhebrew}{05B9} \pdfglyphtounicode{holamwidehebrew}{05B9} \pdfglyphtounicode{honokhukthai}{0E2E} \pdfglyphtounicode{hookabovecomb}{0309} \pdfglyphtounicode{hookcmb}{0309} \pdfglyphtounicode{hookpalatalizedbelowcmb}{0321} \pdfglyphtounicode{hookretroflexbelowcmb}{0322} \pdfglyphtounicode{hoonsquare}{3342} \pdfglyphtounicode{horicoptic}{03E9} \pdfglyphtounicode{horizontalbar}{2015} \pdfglyphtounicode{horncmb}{031B} \pdfglyphtounicode{hotsprings}{2668} \pdfglyphtounicode{house}{2302} \pdfglyphtounicode{hparen}{24A3} \pdfglyphtounicode{hsuperior}{02B0} \pdfglyphtounicode{hturned}{0265} \pdfglyphtounicode{huhiragana}{3075} \pdfglyphtounicode{huiitosquare}{3333} \pdfglyphtounicode{hukatakana}{30D5} \pdfglyphtounicode{hukatakanahalfwidth}{FF8C} \pdfglyphtounicode{hungarumlaut}{02DD} \pdfglyphtounicode{hungarumlautcmb}{030B} \pdfglyphtounicode{hv}{0195} \pdfglyphtounicode{hyphen}{002D} \pdfglyphtounicode{hyphenchar}{002D} \pdfglyphtounicode{hypheninferior}{002D} \pdfglyphtounicode{hyphenmonospace}{FF0D} \pdfglyphtounicode{hyphensmall}{FE63} \pdfglyphtounicode{hyphensuperior}{002D} \pdfglyphtounicode{hyphentwo}{2010} \pdfglyphtounicode{i}{0069} \pdfglyphtounicode{iacute}{00ED} \pdfglyphtounicode{iacyrillic}{044F} \pdfglyphtounicode{ibengali}{0987} \pdfglyphtounicode{ibopomofo}{3127} \pdfglyphtounicode{ibreve}{012D} \pdfglyphtounicode{icaron}{01D0} \pdfglyphtounicode{icircle}{24D8} \pdfglyphtounicode{icircumflex}{00EE} \pdfglyphtounicode{icyrillic}{0456} \pdfglyphtounicode{idblgrave}{0209} \pdfglyphtounicode{ideographearthcircle}{328F} \pdfglyphtounicode{ideographfirecircle}{328B} \pdfglyphtounicode{ideographicallianceparen}{323F} \pdfglyphtounicode{ideographiccallparen}{323A} \pdfglyphtounicode{ideographiccentrecircle}{32A5} \pdfglyphtounicode{ideographicclose}{3006} \pdfglyphtounicode{ideographiccomma}{3001} \pdfglyphtounicode{ideographiccommaleft}{FF64} \pdfglyphtounicode{ideographiccongratulationparen}{3237} \pdfglyphtounicode{ideographiccorrectcircle}{32A3} \pdfglyphtounicode{ideographicearthparen}{322F} \pdfglyphtounicode{ideographicenterpriseparen}{323D} \pdfglyphtounicode{ideographicexcellentcircle}{329D} \pdfglyphtounicode{ideographicfestivalparen}{3240} \pdfglyphtounicode{ideographicfinancialcircle}{3296} \pdfglyphtounicode{ideographicfinancialparen}{3236} \pdfglyphtounicode{ideographicfireparen}{322B} \pdfglyphtounicode{ideographichaveparen}{3232} \pdfglyphtounicode{ideographichighcircle}{32A4} \pdfglyphtounicode{ideographiciterationmark}{3005} \pdfglyphtounicode{ideographiclaborcircle}{3298} \pdfglyphtounicode{ideographiclaborparen}{3238} \pdfglyphtounicode{ideographicleftcircle}{32A7} \pdfglyphtounicode{ideographiclowcircle}{32A6} \pdfglyphtounicode{ideographicmedicinecircle}{32A9} \pdfglyphtounicode{ideographicmetalparen}{322E} \pdfglyphtounicode{ideographicmoonparen}{322A} \pdfglyphtounicode{ideographicnameparen}{3234} \pdfglyphtounicode{ideographicperiod}{3002} \pdfglyphtounicode{ideographicprintcircle}{329E} \pdfglyphtounicode{ideographicreachparen}{3243} \pdfglyphtounicode{ideographicrepresentparen}{3239} \pdfglyphtounicode{ideographicresourceparen}{323E} \pdfglyphtounicode{ideographicrightcircle}{32A8} \pdfglyphtounicode{ideographicsecretcircle}{3299} \pdfglyphtounicode{ideographicselfparen}{3242} \pdfglyphtounicode{ideographicsocietyparen}{3233} \pdfglyphtounicode{ideographicspace}{3000} \pdfglyphtounicode{ideographicspecialparen}{3235} \pdfglyphtounicode{ideographicstockparen}{3231} \pdfglyphtounicode{ideographicstudyparen}{323B} \pdfglyphtounicode{ideographicsunparen}{3230} \pdfglyphtounicode{ideographicsuperviseparen}{323C} \pdfglyphtounicode{ideographicwaterparen}{322C} \pdfglyphtounicode{ideographicwoodparen}{322D} \pdfglyphtounicode{ideographiczero}{3007} \pdfglyphtounicode{ideographmetalcircle}{328E} \pdfglyphtounicode{ideographmooncircle}{328A} \pdfglyphtounicode{ideographnamecircle}{3294} \pdfglyphtounicode{ideographsuncircle}{3290} \pdfglyphtounicode{ideographwatercircle}{328C} \pdfglyphtounicode{ideographwoodcircle}{328D} \pdfglyphtounicode{ideva}{0907} \pdfglyphtounicode{idieresis}{00EF} \pdfglyphtounicode{idieresisacute}{1E2F} \pdfglyphtounicode{idieresiscyrillic}{04E5} \pdfglyphtounicode{idotbelow}{1ECB} \pdfglyphtounicode{iebrevecyrillic}{04D7} \pdfglyphtounicode{iecyrillic}{0435} \pdfglyphtounicode{ieungacirclekorean}{3275} \pdfglyphtounicode{ieungaparenkorean}{3215} \pdfglyphtounicode{ieungcirclekorean}{3267} \pdfglyphtounicode{ieungkorean}{3147} \pdfglyphtounicode{ieungparenkorean}{3207} \pdfglyphtounicode{igrave}{00EC} \pdfglyphtounicode{igujarati}{0A87} \pdfglyphtounicode{igurmukhi}{0A07} \pdfglyphtounicode{ihiragana}{3044} \pdfglyphtounicode{ihookabove}{1EC9} \pdfglyphtounicode{iibengali}{0988} \pdfglyphtounicode{iicyrillic}{0438} \pdfglyphtounicode{iideva}{0908} \pdfglyphtounicode{iigujarati}{0A88} \pdfglyphtounicode{iigurmukhi}{0A08} \pdfglyphtounicode{iimatragurmukhi}{0A40} \pdfglyphtounicode{iinvertedbreve}{020B} \pdfglyphtounicode{iishortcyrillic}{0439} \pdfglyphtounicode{iivowelsignbengali}{09C0} \pdfglyphtounicode{iivowelsigndeva}{0940} \pdfglyphtounicode{iivowelsigngujarati}{0AC0} \pdfglyphtounicode{ij}{0133} \pdfglyphtounicode{ikatakana}{30A4} \pdfglyphtounicode{ikatakanahalfwidth}{FF72} \pdfglyphtounicode{ikorean}{3163} \pdfglyphtounicode{ilde}{02DC} \pdfglyphtounicode{iluyhebrew}{05AC} \pdfglyphtounicode{imacron}{012B} \pdfglyphtounicode{imacroncyrillic}{04E3} \pdfglyphtounicode{imageorapproximatelyequal}{2253} \pdfglyphtounicode{imatragurmukhi}{0A3F} \pdfglyphtounicode{imonospace}{FF49} \pdfglyphtounicode{increment}{2206} \pdfglyphtounicode{infinity}{221E} \pdfglyphtounicode{iniarmenian}{056B} \pdfglyphtounicode{integerdivide}{2216} \pdfglyphtounicode{integral}{222B} \pdfglyphtounicode{integralbottom}{2321} \pdfglyphtounicode{integralbt}{2321} \pdfglyphtounicode{integralex}{F8F5} \pdfglyphtounicode{integraltop}{2320} \pdfglyphtounicode{integraltp}{2320} \pdfglyphtounicode{intercal}{22BA} \pdfglyphtounicode{interrobang}{203D} \pdfglyphtounicode{interrobangdown}{2E18} \pdfglyphtounicode{intersection}{2229} \pdfglyphtounicode{intersectiondbl}{22D2} \pdfglyphtounicode{intersectionsq}{2293} \pdfglyphtounicode{intisquare}{3305} \pdfglyphtounicode{invbullet}{25D8} \pdfglyphtounicode{invcircle}{25D9} \pdfglyphtounicode{invsmileface}{263B} \pdfglyphtounicode{iocyrillic}{0451} \pdfglyphtounicode{iogonek}{012F} \pdfglyphtounicode{iota}{03B9} \pdfglyphtounicode{iotadieresis}{03CA} \pdfglyphtounicode{iotadieresistonos}{0390} \pdfglyphtounicode{iotalatin}{0269} \pdfglyphtounicode{iotatonos}{03AF} \pdfglyphtounicode{iparen}{24A4} \pdfglyphtounicode{irigurmukhi}{0A72} \pdfglyphtounicode{ismallhiragana}{3043} \pdfglyphtounicode{ismallkatakana}{30A3} \pdfglyphtounicode{ismallkatakanahalfwidth}{FF68} \pdfglyphtounicode{issharbengali}{09FA} \pdfglyphtounicode{istroke}{0268} \pdfglyphtounicode{isuperior}{0069} \pdfglyphtounicode{iterationhiragana}{309D} \pdfglyphtounicode{iterationkatakana}{30FD} \pdfglyphtounicode{itilde}{0129} \pdfglyphtounicode{itildebelow}{1E2D} \pdfglyphtounicode{iubopomofo}{3129} \pdfglyphtounicode{iucyrillic}{044E} \pdfglyphtounicode{ivowelsignbengali}{09BF} \pdfglyphtounicode{ivowelsigndeva}{093F} \pdfglyphtounicode{ivowelsigngujarati}{0ABF} \pdfglyphtounicode{izhitsacyrillic}{0475} \pdfglyphtounicode{izhitsadblgravecyrillic}{0477} \pdfglyphtounicode{j}{006A} \pdfglyphtounicode{jaarmenian}{0571} \pdfglyphtounicode{jabengali}{099C} \pdfglyphtounicode{jadeva}{091C} \pdfglyphtounicode{jagujarati}{0A9C} \pdfglyphtounicode{jagurmukhi}{0A1C} \pdfglyphtounicode{jbopomofo}{3110} \pdfglyphtounicode{jcaron}{01F0} \pdfglyphtounicode{jcircle}{24D9} \pdfglyphtounicode{jcircumflex}{0135} \pdfglyphtounicode{jcrossedtail}{029D} \pdfglyphtounicode{jdotlessstroke}{025F} \pdfglyphtounicode{jecyrillic}{0458} \pdfglyphtounicode{jeemarabic}{062C} \pdfglyphtounicode{jeemfinalarabic}{FE9E} \pdfglyphtounicode{jeeminitialarabic}{FE9F} \pdfglyphtounicode{jeemmedialarabic}{FEA0} \pdfglyphtounicode{jeharabic}{0698} \pdfglyphtounicode{jehfinalarabic}{FB8B} \pdfglyphtounicode{jhabengali}{099D} \pdfglyphtounicode{jhadeva}{091D} \pdfglyphtounicode{jhagujarati}{0A9D} \pdfglyphtounicode{jhagurmukhi}{0A1D} \pdfglyphtounicode{jheharmenian}{057B} \pdfglyphtounicode{jis}{3004} \pdfglyphtounicode{jmonospace}{FF4A} \pdfglyphtounicode{jparen}{24A5} \pdfglyphtounicode{jsuperior}{02B2} \pdfglyphtounicode{k}{006B} \pdfglyphtounicode{kabashkircyrillic}{04A1} \pdfglyphtounicode{kabengali}{0995} \pdfglyphtounicode{kacute}{1E31} \pdfglyphtounicode{kacyrillic}{043A} \pdfglyphtounicode{kadescendercyrillic}{049B} \pdfglyphtounicode{kadeva}{0915} \pdfglyphtounicode{kaf}{05DB} \pdfglyphtounicode{kafarabic}{0643} \pdfglyphtounicode{kafdagesh}{FB3B} \pdfglyphtounicode{kafdageshhebrew}{FB3B} \pdfglyphtounicode{kaffinalarabic}{FEDA} \pdfglyphtounicode{kafhebrew}{05DB} \pdfglyphtounicode{kafinitialarabic}{FEDB} \pdfglyphtounicode{kafmedialarabic}{FEDC} \pdfglyphtounicode{kafrafehebrew}{FB4D} \pdfglyphtounicode{kagujarati}{0A95} \pdfglyphtounicode{kagurmukhi}{0A15} \pdfglyphtounicode{kahiragana}{304B} \pdfglyphtounicode{kahookcyrillic}{04C4} \pdfglyphtounicode{kakatakana}{30AB} \pdfglyphtounicode{kakatakanahalfwidth}{FF76} \pdfglyphtounicode{kappa}{03BA} \pdfglyphtounicode{kappasymbolgreek}{03F0} \pdfglyphtounicode{kapyeounmieumkorean}{3171} \pdfglyphtounicode{kapyeounphieuphkorean}{3184} \pdfglyphtounicode{kapyeounpieupkorean}{3178} \pdfglyphtounicode{kapyeounssangpieupkorean}{3179} \pdfglyphtounicode{karoriisquare}{330D} \pdfglyphtounicode{kashidaautoarabic}{0640} \pdfglyphtounicode{kashidaautonosidebearingarabic}{0640} \pdfglyphtounicode{kasmallkatakana}{30F5} \pdfglyphtounicode{kasquare}{3384} \pdfglyphtounicode{kasraarabic}{0650} \pdfglyphtounicode{kasratanarabic}{064D} \pdfglyphtounicode{kastrokecyrillic}{049F} \pdfglyphtounicode{katahiraprolongmarkhalfwidth}{FF70} \pdfglyphtounicode{kaverticalstrokecyrillic}{049D} \pdfglyphtounicode{kbopomofo}{310E} \pdfglyphtounicode{kcalsquare}{3389} \pdfglyphtounicode{kcaron}{01E9} \pdfglyphtounicode{kcedilla}{0137} \pdfglyphtounicode{kcircle}{24DA} \pdfglyphtounicode{kcommaaccent}{0137} \pdfglyphtounicode{kdotbelow}{1E33} \pdfglyphtounicode{keharmenian}{0584} \pdfglyphtounicode{kehiragana}{3051} \pdfglyphtounicode{kekatakana}{30B1} \pdfglyphtounicode{kekatakanahalfwidth}{FF79} \pdfglyphtounicode{kenarmenian}{056F} \pdfglyphtounicode{kesmallkatakana}{30F6} \pdfglyphtounicode{kgreenlandic}{0138} \pdfglyphtounicode{khabengali}{0996} \pdfglyphtounicode{khacyrillic}{0445} \pdfglyphtounicode{khadeva}{0916} \pdfglyphtounicode{khagujarati}{0A96} \pdfglyphtounicode{khagurmukhi}{0A16} \pdfglyphtounicode{khaharabic}{062E} \pdfglyphtounicode{khahfinalarabic}{FEA6} \pdfglyphtounicode{khahinitialarabic}{FEA7} \pdfglyphtounicode{khahmedialarabic}{FEA8} \pdfglyphtounicode{kheicoptic}{03E7} \pdfglyphtounicode{khhadeva}{0959} \pdfglyphtounicode{khhagurmukhi}{0A59} \pdfglyphtounicode{khieukhacirclekorean}{3278} \pdfglyphtounicode{khieukhaparenkorean}{3218} \pdfglyphtounicode{khieukhcirclekorean}{326A} \pdfglyphtounicode{khieukhkorean}{314B} \pdfglyphtounicode{khieukhparenkorean}{320A} \pdfglyphtounicode{khokhaithai}{0E02} \pdfglyphtounicode{khokhonthai}{0E05} \pdfglyphtounicode{khokhuatthai}{0E03} \pdfglyphtounicode{khokhwaithai}{0E04} \pdfglyphtounicode{khomutthai}{0E5B} \pdfglyphtounicode{khook}{0199} \pdfglyphtounicode{khorakhangthai}{0E06} \pdfglyphtounicode{khzsquare}{3391} \pdfglyphtounicode{kihiragana}{304D} \pdfglyphtounicode{kikatakana}{30AD} \pdfglyphtounicode{kikatakanahalfwidth}{FF77} \pdfglyphtounicode{kiroguramusquare}{3315} \pdfglyphtounicode{kiromeetorusquare}{3316} \pdfglyphtounicode{kirosquare}{3314} \pdfglyphtounicode{kiyeokacirclekorean}{326E} \pdfglyphtounicode{kiyeokaparenkorean}{320E} \pdfglyphtounicode{kiyeokcirclekorean}{3260} \pdfglyphtounicode{kiyeokkorean}{3131} \pdfglyphtounicode{kiyeokparenkorean}{3200} \pdfglyphtounicode{kiyeoksioskorean}{3133} \pdfglyphtounicode{kjecyrillic}{045C} \pdfglyphtounicode{klinebelow}{1E35} \pdfglyphtounicode{klsquare}{3398} \pdfglyphtounicode{kmcubedsquare}{33A6} \pdfglyphtounicode{kmonospace}{FF4B} \pdfglyphtounicode{kmsquaredsquare}{33A2} \pdfglyphtounicode{kohiragana}{3053} \pdfglyphtounicode{kohmsquare}{33C0} \pdfglyphtounicode{kokaithai}{0E01} \pdfglyphtounicode{kokatakana}{30B3} \pdfglyphtounicode{kokatakanahalfwidth}{FF7A} \pdfglyphtounicode{kooposquare}{331E} \pdfglyphtounicode{koppacyrillic}{0481} \pdfglyphtounicode{koreanstandardsymbol}{327F} \pdfglyphtounicode{koroniscmb}{0343} \pdfglyphtounicode{kparen}{24A6} \pdfglyphtounicode{kpasquare}{33AA} \pdfglyphtounicode{ksicyrillic}{046F} \pdfglyphtounicode{ktsquare}{33CF} \pdfglyphtounicode{kturned}{029E} \pdfglyphtounicode{kuhiragana}{304F} \pdfglyphtounicode{kukatakana}{30AF} \pdfglyphtounicode{kukatakanahalfwidth}{FF78} \pdfglyphtounicode{kvsquare}{33B8} \pdfglyphtounicode{kwsquare}{33BE} \pdfglyphtounicode{l}{006C} \pdfglyphtounicode{labengali}{09B2} \pdfglyphtounicode{lacute}{013A} \pdfglyphtounicode{ladeva}{0932} \pdfglyphtounicode{lagujarati}{0AB2} \pdfglyphtounicode{lagurmukhi}{0A32} \pdfglyphtounicode{lakkhangyaothai}{0E45} \pdfglyphtounicode{lamaleffinalarabic}{FEFC} \pdfglyphtounicode{lamalefhamzaabovefinalarabic}{FEF8} \pdfglyphtounicode{lamalefhamzaaboveisolatedarabic}{FEF7} \pdfglyphtounicode{lamalefhamzabelowfinalarabic}{FEFA} \pdfglyphtounicode{lamalefhamzabelowisolatedarabic}{FEF9} \pdfglyphtounicode{lamalefisolatedarabic}{FEFB} \pdfglyphtounicode{lamalefmaddaabovefinalarabic}{FEF6} \pdfglyphtounicode{lamalefmaddaaboveisolatedarabic}{FEF5} \pdfglyphtounicode{lamarabic}{0644} \pdfglyphtounicode{lambda}{03BB} \pdfglyphtounicode{lambdastroke}{019B} \pdfglyphtounicode{lamed}{05DC} \pdfglyphtounicode{lameddagesh}{FB3C} \pdfglyphtounicode{lameddageshhebrew}{FB3C} \pdfglyphtounicode{lamedhebrew}{05DC} \pdfglyphtounicode{lamedholam}{05DC 05B9} \pdfglyphtounicode{lamedholamdagesh}{05DC 05B9 05BC} \pdfglyphtounicode{lamedholamdageshhebrew}{05DC 05B9 05BC} \pdfglyphtounicode{lamedholamhebrew}{05DC 05B9} \pdfglyphtounicode{lamfinalarabic}{FEDE} \pdfglyphtounicode{lamhahinitialarabic}{FCCA} \pdfglyphtounicode{laminitialarabic}{FEDF} \pdfglyphtounicode{lamjeeminitialarabic}{FCC9} \pdfglyphtounicode{lamkhahinitialarabic}{FCCB} \pdfglyphtounicode{lamlamhehisolatedarabic}{FDF2} \pdfglyphtounicode{lammedialarabic}{FEE0} \pdfglyphtounicode{lammeemhahinitialarabic}{FD88} \pdfglyphtounicode{lammeeminitialarabic}{FCCC} \pdfglyphtounicode{lammeemjeeminitialarabic}{FEDF FEE4 FEA0} \pdfglyphtounicode{lammeemkhahinitialarabic}{FEDF FEE4 FEA8} \pdfglyphtounicode{largecircle}{25EF} \pdfglyphtounicode{latticetop}{22A4} \pdfglyphtounicode{lbar}{019A} \pdfglyphtounicode{lbelt}{026C} \pdfglyphtounicode{lbopomofo}{310C} \pdfglyphtounicode{lcaron}{013E} \pdfglyphtounicode{lcedilla}{013C} \pdfglyphtounicode{lcircle}{24DB} \pdfglyphtounicode{lcircumflexbelow}{1E3D} \pdfglyphtounicode{lcommaaccent}{013C} \pdfglyphtounicode{ldot}{0140} \pdfglyphtounicode{ldotaccent}{0140} \pdfglyphtounicode{ldotbelow}{1E37} \pdfglyphtounicode{ldotbelowmacron}{1E39} \pdfglyphtounicode{leftangleabovecmb}{031A} \pdfglyphtounicode{lefttackbelowcmb}{0318} \pdfglyphtounicode{less}{003C} \pdfglyphtounicode{lessdbleqlgreater}{2A8B} \pdfglyphtounicode{lessdblequal}{2266} \pdfglyphtounicode{lessdot}{22D6} \pdfglyphtounicode{lessequal}{2264} \pdfglyphtounicode{lessequalgreater}{22DA} \pdfglyphtounicode{lessequalorgreater}{22DA} \pdfglyphtounicode{lessmonospace}{FF1C} \pdfglyphtounicode{lessmuch}{226A} \pdfglyphtounicode{lessnotdblequal}{2A89} \pdfglyphtounicode{lessnotequal}{2A87} \pdfglyphtounicode{lessorapproxeql}{2A85} \pdfglyphtounicode{lessorequalslant}{2A7D} \pdfglyphtounicode{lessorequivalent}{2272} \pdfglyphtounicode{lessorgreater}{2276} \pdfglyphtounicode{lessornotdbleql}{2268} \pdfglyphtounicode{lessornotequal}{2268} \pdfglyphtounicode{lessorsimilar}{2272} \pdfglyphtounicode{lessoverequal}{2266} \pdfglyphtounicode{lesssmall}{FE64} \pdfglyphtounicode{lezh}{026E} \pdfglyphtounicode{lfblock}{258C} \pdfglyphtounicode{lhookretroflex}{026D} \pdfglyphtounicode{lira}{20A4} \pdfglyphtounicode{liwnarmenian}{056C} \pdfglyphtounicode{lj}{01C9} \pdfglyphtounicode{ljecyrillic}{0459} \pdfglyphtounicode{ll}{006C 006C} \pdfglyphtounicode{lladeva}{0933} \pdfglyphtounicode{llagujarati}{0AB3} \pdfglyphtounicode{llinebelow}{1E3B} \pdfglyphtounicode{llladeva}{0934} \pdfglyphtounicode{llvocalicbengali}{09E1} \pdfglyphtounicode{llvocalicdeva}{0961} \pdfglyphtounicode{llvocalicvowelsignbengali}{09E3} \pdfglyphtounicode{llvocalicvowelsigndeva}{0963} \pdfglyphtounicode{lmiddletilde}{026B} \pdfglyphtounicode{lmonospace}{FF4C} \pdfglyphtounicode{lmsquare}{33D0} \pdfglyphtounicode{lochulathai}{0E2C} \pdfglyphtounicode{logicaland}{2227} \pdfglyphtounicode{logicalnot}{00AC} \pdfglyphtounicode{logicalnotreversed}{2310} \pdfglyphtounicode{logicalor}{2228} \pdfglyphtounicode{lolingthai}{0E25} \pdfglyphtounicode{longdbls}{017F 017F} \pdfglyphtounicode{longs}{017F} \pdfglyphtounicode{longsh}{017F 0068} \pdfglyphtounicode{longsi}{017F 0069} \pdfglyphtounicode{longsl}{017F 006C} \pdfglyphtounicode{longst}{017F 0074} \pdfglyphtounicode{lowlinecenterline}{FE4E} \pdfglyphtounicode{lowlinecmb}{0332} \pdfglyphtounicode{lowlinedashed}{FE4D} \pdfglyphtounicode{lozenge}{25CA} \pdfglyphtounicode{lparen}{24A7} \pdfglyphtounicode{lscript}{2113} \pdfglyphtounicode{lslash}{0142} \pdfglyphtounicode{lsquare}{2113} \pdfglyphtounicode{lsuperior}{006C} \pdfglyphtounicode{ltshade}{2591} \pdfglyphtounicode{luthai}{0E26} \pdfglyphtounicode{lvocalicbengali}{098C} \pdfglyphtounicode{lvocalicdeva}{090C} \pdfglyphtounicode{lvocalicvowelsignbengali}{09E2} \pdfglyphtounicode{lvocalicvowelsigndeva}{0962} \pdfglyphtounicode{lxsquare}{33D3} \pdfglyphtounicode{m}{006D} \pdfglyphtounicode{mabengali}{09AE} \pdfglyphtounicode{macron}{00AF} \pdfglyphtounicode{macronbelowcmb}{0331} \pdfglyphtounicode{macroncmb}{0304} \pdfglyphtounicode{macronlowmod}{02CD} \pdfglyphtounicode{macronmonospace}{FFE3} \pdfglyphtounicode{macute}{1E3F} \pdfglyphtounicode{madeva}{092E} \pdfglyphtounicode{magujarati}{0AAE} \pdfglyphtounicode{magurmukhi}{0A2E} \pdfglyphtounicode{mahapakhhebrew}{05A4} \pdfglyphtounicode{mahapakhlefthebrew}{05A4} \pdfglyphtounicode{mahiragana}{307E} \pdfglyphtounicode{maichattawalowleftthai}{F895} \pdfglyphtounicode{maichattawalowrightthai}{F894} \pdfglyphtounicode{maichattawathai}{0E4B} \pdfglyphtounicode{maichattawaupperleftthai}{F893} \pdfglyphtounicode{maieklowleftthai}{F88C} \pdfglyphtounicode{maieklowrightthai}{F88B} \pdfglyphtounicode{maiekthai}{0E48} \pdfglyphtounicode{maiekupperleftthai}{F88A} \pdfglyphtounicode{maihanakatleftthai}{F884} \pdfglyphtounicode{maihanakatthai}{0E31} \pdfglyphtounicode{maitaikhuleftthai}{F889} \pdfglyphtounicode{maitaikhuthai}{0E47} \pdfglyphtounicode{maitholowleftthai}{F88F} \pdfglyphtounicode{maitholowrightthai}{F88E} \pdfglyphtounicode{maithothai}{0E49} \pdfglyphtounicode{maithoupperleftthai}{F88D} \pdfglyphtounicode{maitrilowleftthai}{F892} \pdfglyphtounicode{maitrilowrightthai}{F891} \pdfglyphtounicode{maitrithai}{0E4A} \pdfglyphtounicode{maitriupperleftthai}{F890} \pdfglyphtounicode{maiyamokthai}{0E46} \pdfglyphtounicode{makatakana}{30DE} \pdfglyphtounicode{makatakanahalfwidth}{FF8F} \pdfglyphtounicode{male}{2642} \pdfglyphtounicode{maltesecross}{2720} \pdfglyphtounicode{mansyonsquare}{3347} \pdfglyphtounicode{maqafhebrew}{05BE} \pdfglyphtounicode{mars}{2642} \pdfglyphtounicode{masoracirclehebrew}{05AF} \pdfglyphtounicode{masquare}{3383} \pdfglyphtounicode{mbopomofo}{3107} \pdfglyphtounicode{mbsquare}{33D4} \pdfglyphtounicode{mcircle}{24DC} \pdfglyphtounicode{mcubedsquare}{33A5} \pdfglyphtounicode{mdotaccent}{1E41} \pdfglyphtounicode{mdotbelow}{1E43} \pdfglyphtounicode{measuredangle}{2221} \pdfglyphtounicode{meemarabic}{0645} \pdfglyphtounicode{meemfinalarabic}{FEE2} \pdfglyphtounicode{meeminitialarabic}{FEE3} \pdfglyphtounicode{meemmedialarabic}{FEE4} \pdfglyphtounicode{meemmeeminitialarabic}{FCD1} \pdfglyphtounicode{meemmeemisolatedarabic}{FC48} \pdfglyphtounicode{meetorusquare}{334D} \pdfglyphtounicode{mehiragana}{3081} \pdfglyphtounicode{meizierasquare}{337E} \pdfglyphtounicode{mekatakana}{30E1} \pdfglyphtounicode{mekatakanahalfwidth}{FF92} \pdfglyphtounicode{mem}{05DE} \pdfglyphtounicode{memdagesh}{FB3E} \pdfglyphtounicode{memdageshhebrew}{FB3E} \pdfglyphtounicode{memhebrew}{05DE} \pdfglyphtounicode{menarmenian}{0574} \pdfglyphtounicode{merkhahebrew}{05A5} \pdfglyphtounicode{merkhakefulahebrew}{05A6} \pdfglyphtounicode{merkhakefulalefthebrew}{05A6} \pdfglyphtounicode{merkhalefthebrew}{05A5} \pdfglyphtounicode{mhook}{0271} \pdfglyphtounicode{mhzsquare}{3392} \pdfglyphtounicode{middledotkatakanahalfwidth}{FF65} \pdfglyphtounicode{middot}{00B7} \pdfglyphtounicode{mieumacirclekorean}{3272} \pdfglyphtounicode{mieumaparenkorean}{3212} \pdfglyphtounicode{mieumcirclekorean}{3264} \pdfglyphtounicode{mieumkorean}{3141} \pdfglyphtounicode{mieumpansioskorean}{3170} \pdfglyphtounicode{mieumparenkorean}{3204} \pdfglyphtounicode{mieumpieupkorean}{316E} \pdfglyphtounicode{mieumsioskorean}{316F} \pdfglyphtounicode{mihiragana}{307F} \pdfglyphtounicode{mikatakana}{30DF} \pdfglyphtounicode{mikatakanahalfwidth}{FF90} \pdfglyphtounicode{minus}{2212} \pdfglyphtounicode{minusbelowcmb}{0320} \pdfglyphtounicode{minuscircle}{2296} \pdfglyphtounicode{minusmod}{02D7} \pdfglyphtounicode{minusplus}{2213} \pdfglyphtounicode{minute}{2032} \pdfglyphtounicode{miribaarusquare}{334A} \pdfglyphtounicode{mirisquare}{3349} \pdfglyphtounicode{mlonglegturned}{0270} \pdfglyphtounicode{mlsquare}{3396} \pdfglyphtounicode{mmcubedsquare}{33A3} \pdfglyphtounicode{mmonospace}{FF4D} \pdfglyphtounicode{mmsquaredsquare}{339F} \pdfglyphtounicode{mohiragana}{3082} \pdfglyphtounicode{mohmsquare}{33C1} \pdfglyphtounicode{mokatakana}{30E2} \pdfglyphtounicode{mokatakanahalfwidth}{FF93} \pdfglyphtounicode{molsquare}{33D6} \pdfglyphtounicode{momathai}{0E21} \pdfglyphtounicode{moverssquare}{33A7} \pdfglyphtounicode{moverssquaredsquare}{33A8} \pdfglyphtounicode{mparen}{24A8} \pdfglyphtounicode{mpasquare}{33AB} \pdfglyphtounicode{mssquare}{33B3} \pdfglyphtounicode{msuperior}{006D} \pdfglyphtounicode{mturned}{026F} \pdfglyphtounicode{mu}{00B5} \pdfglyphtounicode{mu1}{00B5} \pdfglyphtounicode{muasquare}{3382} \pdfglyphtounicode{muchgreater}{226B} \pdfglyphtounicode{muchless}{226A} \pdfglyphtounicode{mufsquare}{338C} \pdfglyphtounicode{mugreek}{03BC} \pdfglyphtounicode{mugsquare}{338D} \pdfglyphtounicode{muhiragana}{3080} \pdfglyphtounicode{mukatakana}{30E0} \pdfglyphtounicode{mukatakanahalfwidth}{FF91} \pdfglyphtounicode{mulsquare}{3395} \pdfglyphtounicode{multicloseleft}{22C9} \pdfglyphtounicode{multicloseright}{22CA} \pdfglyphtounicode{multimap}{22B8} \pdfglyphtounicode{multiopenleft}{22CB} \pdfglyphtounicode{multiopenright}{22CC} \pdfglyphtounicode{multiply}{00D7} \pdfglyphtounicode{mumsquare}{339B} \pdfglyphtounicode{munahhebrew}{05A3} \pdfglyphtounicode{munahlefthebrew}{05A3} \pdfglyphtounicode{musicalnote}{266A} \pdfglyphtounicode{musicalnotedbl}{266B} \pdfglyphtounicode{musicflatsign}{266D} \pdfglyphtounicode{musicsharpsign}{266F} \pdfglyphtounicode{mussquare}{33B2} \pdfglyphtounicode{muvsquare}{33B6} \pdfglyphtounicode{muwsquare}{33BC} \pdfglyphtounicode{mvmegasquare}{33B9} \pdfglyphtounicode{mvsquare}{33B7} \pdfglyphtounicode{mwmegasquare}{33BF} \pdfglyphtounicode{mwsquare}{33BD} \pdfglyphtounicode{n}{006E} \pdfglyphtounicode{nabengali}{09A8} \pdfglyphtounicode{nabla}{2207} \pdfglyphtounicode{nacute}{0144} \pdfglyphtounicode{nadeva}{0928} \pdfglyphtounicode{nagujarati}{0AA8} \pdfglyphtounicode{nagurmukhi}{0A28} \pdfglyphtounicode{nahiragana}{306A} \pdfglyphtounicode{nakatakana}{30CA} \pdfglyphtounicode{nakatakanahalfwidth}{FF85} \pdfglyphtounicode{nand}{22BC} \pdfglyphtounicode{napostrophe}{0149} \pdfglyphtounicode{nasquare}{3381} \pdfglyphtounicode{natural}{266E} \pdfglyphtounicode{nbopomofo}{310B} \pdfglyphtounicode{nbspace}{00A0} \pdfglyphtounicode{ncaron}{0148} \pdfglyphtounicode{ncedilla}{0146} \pdfglyphtounicode{ncircle}{24DD} \pdfglyphtounicode{ncircumflexbelow}{1E4B} \pdfglyphtounicode{ncommaaccent}{0146} \pdfglyphtounicode{ndotaccent}{1E45} \pdfglyphtounicode{ndotbelow}{1E47} \pdfglyphtounicode{negationslash}{0338} \pdfglyphtounicode{nehiragana}{306D} \pdfglyphtounicode{nekatakana}{30CD} \pdfglyphtounicode{nekatakanahalfwidth}{FF88} \pdfglyphtounicode{newsheqelsign}{20AA} \pdfglyphtounicode{nfsquare}{338B} \pdfglyphtounicode{ng}{014B} \pdfglyphtounicode{ngabengali}{0999} \pdfglyphtounicode{ngadeva}{0919} \pdfglyphtounicode{ngagujarati}{0A99} \pdfglyphtounicode{ngagurmukhi}{0A19} \pdfglyphtounicode{ngonguthai}{0E07} \pdfglyphtounicode{nhiragana}{3093} \pdfglyphtounicode{nhookleft}{0272} \pdfglyphtounicode{nhookretroflex}{0273} \pdfglyphtounicode{nieunacirclekorean}{326F} \pdfglyphtounicode{nieunaparenkorean}{320F} \pdfglyphtounicode{nieuncieuckorean}{3135} \pdfglyphtounicode{nieuncirclekorean}{3261} \pdfglyphtounicode{nieunhieuhkorean}{3136} \pdfglyphtounicode{nieunkorean}{3134} \pdfglyphtounicode{nieunpansioskorean}{3168} \pdfglyphtounicode{nieunparenkorean}{3201} \pdfglyphtounicode{nieunsioskorean}{3167} \pdfglyphtounicode{nieuntikeutkorean}{3166} \pdfglyphtounicode{nihiragana}{306B} \pdfglyphtounicode{nikatakana}{30CB} \pdfglyphtounicode{nikatakanahalfwidth}{FF86} \pdfglyphtounicode{nikhahitleftthai}{F899} \pdfglyphtounicode{nikhahitthai}{0E4D} \pdfglyphtounicode{nine}{0039} \pdfglyphtounicode{ninearabic}{0669} \pdfglyphtounicode{ninebengali}{09EF} \pdfglyphtounicode{ninecircle}{2468} \pdfglyphtounicode{ninecircleinversesansserif}{2792} \pdfglyphtounicode{ninedeva}{096F} \pdfglyphtounicode{ninegujarati}{0AEF} \pdfglyphtounicode{ninegurmukhi}{0A6F} \pdfglyphtounicode{ninehackarabic}{0669} \pdfglyphtounicode{ninehangzhou}{3029} \pdfglyphtounicode{nineideographicparen}{3228} \pdfglyphtounicode{nineinferior}{2089} \pdfglyphtounicode{ninemonospace}{FF19} \pdfglyphtounicode{nineoldstyle}{0039} \pdfglyphtounicode{nineparen}{247C} \pdfglyphtounicode{nineperiod}{2490} \pdfglyphtounicode{ninepersian}{06F9} \pdfglyphtounicode{nineroman}{2178} \pdfglyphtounicode{ninesuperior}{2079} \pdfglyphtounicode{nineteencircle}{2472} \pdfglyphtounicode{nineteenparen}{2486} \pdfglyphtounicode{nineteenperiod}{249A} \pdfglyphtounicode{ninethai}{0E59} \pdfglyphtounicode{nj}{01CC} \pdfglyphtounicode{njecyrillic}{045A} \pdfglyphtounicode{nkatakana}{30F3} \pdfglyphtounicode{nkatakanahalfwidth}{FF9D} \pdfglyphtounicode{nlegrightlong}{019E} \pdfglyphtounicode{nlinebelow}{1E49} \pdfglyphtounicode{nmonospace}{FF4E} \pdfglyphtounicode{nmsquare}{339A} \pdfglyphtounicode{nnabengali}{09A3} \pdfglyphtounicode{nnadeva}{0923} \pdfglyphtounicode{nnagujarati}{0AA3} \pdfglyphtounicode{nnagurmukhi}{0A23} \pdfglyphtounicode{nnnadeva}{0929} \pdfglyphtounicode{nohiragana}{306E} \pdfglyphtounicode{nokatakana}{30CE} \pdfglyphtounicode{nokatakanahalfwidth}{FF89} \pdfglyphtounicode{nonbreakingspace}{00A0} \pdfglyphtounicode{nonenthai}{0E13} \pdfglyphtounicode{nonuthai}{0E19} \pdfglyphtounicode{noonarabic}{0646} \pdfglyphtounicode{noonfinalarabic}{FEE6} \pdfglyphtounicode{noonghunnaarabic}{06BA} \pdfglyphtounicode{noonghunnafinalarabic}{FB9F} \pdfglyphtounicode{noonhehinitialarabic}{FEE7 FEEC} \pdfglyphtounicode{nooninitialarabic}{FEE7} \pdfglyphtounicode{noonjeeminitialarabic}{FCD2} \pdfglyphtounicode{noonjeemisolatedarabic}{FC4B} \pdfglyphtounicode{noonmedialarabic}{FEE8} \pdfglyphtounicode{noonmeeminitialarabic}{FCD5} \pdfglyphtounicode{noonmeemisolatedarabic}{FC4E} \pdfglyphtounicode{noonnoonfinalarabic}{FC8D} \pdfglyphtounicode{notapproxequal}{2247} \pdfglyphtounicode{notarrowboth}{21AE} \pdfglyphtounicode{notarrowleft}{219A} \pdfglyphtounicode{notarrowright}{219B} \pdfglyphtounicode{notbar}{2224} \pdfglyphtounicode{notcontains}{220C} \pdfglyphtounicode{notdblarrowboth}{21CE} \pdfglyphtounicode{notdblarrowleft}{21CD} \pdfglyphtounicode{notdblarrowright}{21CF} \pdfglyphtounicode{notelement}{2209} \pdfglyphtounicode{notelementof}{2209} \pdfglyphtounicode{notequal}{2260} \pdfglyphtounicode{notexistential}{2204} \pdfglyphtounicode{notfollows}{2281} \pdfglyphtounicode{notfollowsoreql}{2AB0 0338} \pdfglyphtounicode{notforces}{22AE} \pdfglyphtounicode{notforcesextra}{22AF} \pdfglyphtounicode{notgreater}{226F} \pdfglyphtounicode{notgreaterdblequal}{2267 0338} \pdfglyphtounicode{notgreaterequal}{2271} \pdfglyphtounicode{notgreaternorequal}{2271} \pdfglyphtounicode{notgreaternorless}{2279} \pdfglyphtounicode{notgreaterorslnteql}{2A7E 0338} \pdfglyphtounicode{notidentical}{2262} \pdfglyphtounicode{notless}{226E} \pdfglyphtounicode{notlessdblequal}{2266 0338} \pdfglyphtounicode{notlessequal}{2270} \pdfglyphtounicode{notlessnorequal}{2270} \pdfglyphtounicode{notlessorslnteql}{2A7D 0338} \pdfglyphtounicode{notparallel}{2226} \pdfglyphtounicode{notprecedes}{2280} \pdfglyphtounicode{notprecedesoreql}{2AAF 0338} \pdfglyphtounicode{notsatisfies}{22AD} \pdfglyphtounicode{notsimilar}{2241} \pdfglyphtounicode{notsubset}{2284} \pdfglyphtounicode{notsubseteql}{2288} \pdfglyphtounicode{notsubsetordbleql}{2AC5 0338} \pdfglyphtounicode{notsubsetoreql}{228A} \pdfglyphtounicode{notsucceeds}{2281} \pdfglyphtounicode{notsuperset}{2285} \pdfglyphtounicode{notsuperseteql}{2289} \pdfglyphtounicode{notsupersetordbleql}{2AC6 0338} \pdfglyphtounicode{notsupersetoreql}{228B} \pdfglyphtounicode{nottriangeqlleft}{22EC} \pdfglyphtounicode{nottriangeqlright}{22ED} \pdfglyphtounicode{nottriangleleft}{22EA} \pdfglyphtounicode{nottriangleright}{22EB} \pdfglyphtounicode{notturnstile}{22AC} \pdfglyphtounicode{nowarmenian}{0576} \pdfglyphtounicode{nparen}{24A9} \pdfglyphtounicode{nssquare}{33B1} \pdfglyphtounicode{nsuperior}{207F} \pdfglyphtounicode{ntilde}{00F1} \pdfglyphtounicode{nu}{03BD} \pdfglyphtounicode{nuhiragana}{306C} \pdfglyphtounicode{nukatakana}{30CC} \pdfglyphtounicode{nukatakanahalfwidth}{FF87} \pdfglyphtounicode{nuktabengali}{09BC} \pdfglyphtounicode{nuktadeva}{093C} \pdfglyphtounicode{nuktagujarati}{0ABC} \pdfglyphtounicode{nuktagurmukhi}{0A3C} \pdfglyphtounicode{numbersign}{0023} \pdfglyphtounicode{numbersignmonospace}{FF03} \pdfglyphtounicode{numbersignsmall}{FE5F} \pdfglyphtounicode{numeralsigngreek}{0374} \pdfglyphtounicode{numeralsignlowergreek}{0375} \pdfglyphtounicode{numero}{2116} \pdfglyphtounicode{nun}{05E0} \pdfglyphtounicode{nundagesh}{FB40} \pdfglyphtounicode{nundageshhebrew}{FB40} \pdfglyphtounicode{nunhebrew}{05E0} \pdfglyphtounicode{nvsquare}{33B5} \pdfglyphtounicode{nwsquare}{33BB} \pdfglyphtounicode{nyabengali}{099E} \pdfglyphtounicode{nyadeva}{091E} \pdfglyphtounicode{nyagujarati}{0A9E} \pdfglyphtounicode{nyagurmukhi}{0A1E} \pdfglyphtounicode{o}{006F} \pdfglyphtounicode{oacute}{00F3} \pdfglyphtounicode{oangthai}{0E2D} \pdfglyphtounicode{obarred}{0275} \pdfglyphtounicode{obarredcyrillic}{04E9} \pdfglyphtounicode{obarreddieresiscyrillic}{04EB} \pdfglyphtounicode{obengali}{0993} \pdfglyphtounicode{obopomofo}{311B} \pdfglyphtounicode{obreve}{014F} \pdfglyphtounicode{ocandradeva}{0911} \pdfglyphtounicode{ocandragujarati}{0A91} \pdfglyphtounicode{ocandravowelsigndeva}{0949} \pdfglyphtounicode{ocandravowelsigngujarati}{0AC9} \pdfglyphtounicode{ocaron}{01D2} \pdfglyphtounicode{ocircle}{24DE} \pdfglyphtounicode{ocircumflex}{00F4} \pdfglyphtounicode{ocircumflexacute}{1ED1} \pdfglyphtounicode{ocircumflexdotbelow}{1ED9} \pdfglyphtounicode{ocircumflexgrave}{1ED3} \pdfglyphtounicode{ocircumflexhookabove}{1ED5} \pdfglyphtounicode{ocircumflextilde}{1ED7} \pdfglyphtounicode{ocyrillic}{043E} \pdfglyphtounicode{odblacute}{0151} \pdfglyphtounicode{odblgrave}{020D} \pdfglyphtounicode{odeva}{0913} \pdfglyphtounicode{odieresis}{00F6} \pdfglyphtounicode{odieresiscyrillic}{04E7} \pdfglyphtounicode{odotbelow}{1ECD} \pdfglyphtounicode{oe}{0153} \pdfglyphtounicode{oekorean}{315A} \pdfglyphtounicode{ogonek}{02DB} \pdfglyphtounicode{ogonekcmb}{0328} \pdfglyphtounicode{ograve}{00F2} \pdfglyphtounicode{ogujarati}{0A93} \pdfglyphtounicode{oharmenian}{0585} \pdfglyphtounicode{ohiragana}{304A} \pdfglyphtounicode{ohookabove}{1ECF} \pdfglyphtounicode{ohorn}{01A1} \pdfglyphtounicode{ohornacute}{1EDB} \pdfglyphtounicode{ohorndotbelow}{1EE3} \pdfglyphtounicode{ohorngrave}{1EDD} \pdfglyphtounicode{ohornhookabove}{1EDF} \pdfglyphtounicode{ohorntilde}{1EE1} \pdfglyphtounicode{ohungarumlaut}{0151} \pdfglyphtounicode{oi}{01A3} \pdfglyphtounicode{oinvertedbreve}{020F} \pdfglyphtounicode{okatakana}{30AA} \pdfglyphtounicode{okatakanahalfwidth}{FF75} \pdfglyphtounicode{okorean}{3157} \pdfglyphtounicode{olehebrew}{05AB} \pdfglyphtounicode{omacron}{014D} \pdfglyphtounicode{omacronacute}{1E53} \pdfglyphtounicode{omacrongrave}{1E51} \pdfglyphtounicode{omdeva}{0950} \pdfglyphtounicode{omega}{03C9} \pdfglyphtounicode{omega1}{03D6} \pdfglyphtounicode{omegacyrillic}{0461} \pdfglyphtounicode{omegalatinclosed}{0277} \pdfglyphtounicode{omegaroundcyrillic}{047B} \pdfglyphtounicode{omegatitlocyrillic}{047D} \pdfglyphtounicode{omegatonos}{03CE} \pdfglyphtounicode{omgujarati}{0AD0} \pdfglyphtounicode{omicron}{03BF} \pdfglyphtounicode{omicrontonos}{03CC} \pdfglyphtounicode{omonospace}{FF4F} \pdfglyphtounicode{one}{0031} \pdfglyphtounicode{onearabic}{0661} \pdfglyphtounicode{onebengali}{09E7} \pdfglyphtounicode{onecircle}{2460} \pdfglyphtounicode{onecircleinversesansserif}{278A} \pdfglyphtounicode{onedeva}{0967} \pdfglyphtounicode{onedotenleader}{2024} \pdfglyphtounicode{oneeighth}{215B} \pdfglyphtounicode{onefitted}{0031} \pdfglyphtounicode{onegujarati}{0AE7} \pdfglyphtounicode{onegurmukhi}{0A67} \pdfglyphtounicode{onehackarabic}{0661} \pdfglyphtounicode{onehalf}{00BD} \pdfglyphtounicode{onehangzhou}{3021} \pdfglyphtounicode{oneideographicparen}{3220} \pdfglyphtounicode{oneinferior}{2081} \pdfglyphtounicode{onemonospace}{FF11} \pdfglyphtounicode{onenumeratorbengali}{09F4} \pdfglyphtounicode{oneoldstyle}{0031} \pdfglyphtounicode{oneparen}{2474} \pdfglyphtounicode{oneperiod}{2488} \pdfglyphtounicode{onepersian}{06F1} \pdfglyphtounicode{onequarter}{00BC} \pdfglyphtounicode{oneroman}{2170} \pdfglyphtounicode{onesuperior}{00B9} \pdfglyphtounicode{onethai}{0E51} \pdfglyphtounicode{onethird}{2153} \pdfglyphtounicode{oogonek}{01EB} \pdfglyphtounicode{oogonekmacron}{01ED} \pdfglyphtounicode{oogurmukhi}{0A13} \pdfglyphtounicode{oomatragurmukhi}{0A4B} \pdfglyphtounicode{oopen}{0254} \pdfglyphtounicode{oparen}{24AA} \pdfglyphtounicode{openbullet}{25E6} \pdfglyphtounicode{option}{2325} \pdfglyphtounicode{ordfeminine}{00AA} \pdfglyphtounicode{ordmasculine}{00BA} \pdfglyphtounicode{orthogonal}{221F} \pdfglyphtounicode{orunderscore}{22BB} \pdfglyphtounicode{oshortdeva}{0912} \pdfglyphtounicode{oshortvowelsigndeva}{094A} \pdfglyphtounicode{oslash}{00F8} \pdfglyphtounicode{oslashacute}{01FF} \pdfglyphtounicode{osmallhiragana}{3049} \pdfglyphtounicode{osmallkatakana}{30A9} \pdfglyphtounicode{osmallkatakanahalfwidth}{FF6B} \pdfglyphtounicode{ostrokeacute}{01FF} \pdfglyphtounicode{osuperior}{006F} \pdfglyphtounicode{otcyrillic}{047F} \pdfglyphtounicode{otilde}{00F5} \pdfglyphtounicode{otildeacute}{1E4D} \pdfglyphtounicode{otildedieresis}{1E4F} \pdfglyphtounicode{oubopomofo}{3121} \pdfglyphtounicode{overline}{203E} \pdfglyphtounicode{overlinecenterline}{FE4A} \pdfglyphtounicode{overlinecmb}{0305} \pdfglyphtounicode{overlinedashed}{FE49} \pdfglyphtounicode{overlinedblwavy}{FE4C} \pdfglyphtounicode{overlinewavy}{FE4B} \pdfglyphtounicode{overscore}{00AF} \pdfglyphtounicode{ovowelsignbengali}{09CB} \pdfglyphtounicode{ovowelsigndeva}{094B} \pdfglyphtounicode{ovowelsigngujarati}{0ACB} \pdfglyphtounicode{owner}{220B} \pdfglyphtounicode{p}{0070} \pdfglyphtounicode{paampssquare}{3380} \pdfglyphtounicode{paasentosquare}{332B} \pdfglyphtounicode{pabengali}{09AA} \pdfglyphtounicode{pacute}{1E55} \pdfglyphtounicode{padeva}{092A} \pdfglyphtounicode{pagedown}{21DF} \pdfglyphtounicode{pageup}{21DE} \pdfglyphtounicode{pagujarati}{0AAA} \pdfglyphtounicode{pagurmukhi}{0A2A} \pdfglyphtounicode{pahiragana}{3071} \pdfglyphtounicode{paiyannoithai}{0E2F} \pdfglyphtounicode{pakatakana}{30D1} \pdfglyphtounicode{palatalizationcyrilliccmb}{0484} \pdfglyphtounicode{palochkacyrillic}{04C0} \pdfglyphtounicode{pansioskorean}{317F} \pdfglyphtounicode{paragraph}{00B6} \pdfglyphtounicode{parallel}{2225} \pdfglyphtounicode{parenleft}{0028} \pdfglyphtounicode{parenleftaltonearabic}{FD3E} \pdfglyphtounicode{parenleftbt}{F8ED} \pdfglyphtounicode{parenleftex}{F8EC} \pdfglyphtounicode{parenleftinferior}{208D} \pdfglyphtounicode{parenleftmonospace}{FF08} \pdfglyphtounicode{parenleftsmall}{FE59} \pdfglyphtounicode{parenleftsuperior}{207D} \pdfglyphtounicode{parenlefttp}{F8EB} \pdfglyphtounicode{parenleftvertical}{FE35} \pdfglyphtounicode{parenright}{0029} \pdfglyphtounicode{parenrightaltonearabic}{FD3F} \pdfglyphtounicode{parenrightbt}{F8F8} \pdfglyphtounicode{parenrightex}{F8F7} \pdfglyphtounicode{parenrightinferior}{208E} \pdfglyphtounicode{parenrightmonospace}{FF09} \pdfglyphtounicode{parenrightsmall}{FE5A} \pdfglyphtounicode{parenrightsuperior}{207E} \pdfglyphtounicode{parenrighttp}{F8F6} \pdfglyphtounicode{parenrightvertical}{FE36} \pdfglyphtounicode{partialdiff}{2202} \pdfglyphtounicode{paseqhebrew}{05C0} \pdfglyphtounicode{pashtahebrew}{0599} \pdfglyphtounicode{pasquare}{33A9} \pdfglyphtounicode{patah}{05B7} \pdfglyphtounicode{patah11}{05B7} \pdfglyphtounicode{patah1d}{05B7} \pdfglyphtounicode{patah2a}{05B7} \pdfglyphtounicode{patahhebrew}{05B7} \pdfglyphtounicode{patahnarrowhebrew}{05B7} \pdfglyphtounicode{patahquarterhebrew}{05B7} \pdfglyphtounicode{patahwidehebrew}{05B7} \pdfglyphtounicode{pazerhebrew}{05A1} \pdfglyphtounicode{pbopomofo}{3106} \pdfglyphtounicode{pcircle}{24DF} \pdfglyphtounicode{pdotaccent}{1E57} \pdfglyphtounicode{pe}{05E4} \pdfglyphtounicode{pecyrillic}{043F} \pdfglyphtounicode{pedagesh}{FB44} \pdfglyphtounicode{pedageshhebrew}{FB44} \pdfglyphtounicode{peezisquare}{333B} \pdfglyphtounicode{pefinaldageshhebrew}{FB43} \pdfglyphtounicode{peharabic}{067E} \pdfglyphtounicode{peharmenian}{057A} \pdfglyphtounicode{pehebrew}{05E4} \pdfglyphtounicode{pehfinalarabic}{FB57} \pdfglyphtounicode{pehinitialarabic}{FB58} \pdfglyphtounicode{pehiragana}{307A} \pdfglyphtounicode{pehmedialarabic}{FB59} \pdfglyphtounicode{pekatakana}{30DA} \pdfglyphtounicode{pemiddlehookcyrillic}{04A7} \pdfglyphtounicode{perafehebrew}{FB4E} \pdfglyphtounicode{percent}{0025} \pdfglyphtounicode{percentarabic}{066A} \pdfglyphtounicode{percentmonospace}{FF05} \pdfglyphtounicode{percentsmall}{FE6A} \pdfglyphtounicode{period}{002E} \pdfglyphtounicode{periodarmenian}{0589} \pdfglyphtounicode{periodcentered}{00B7} \pdfglyphtounicode{periodhalfwidth}{FF61} \pdfglyphtounicode{periodinferior}{002E} \pdfglyphtounicode{periodmonospace}{FF0E} \pdfglyphtounicode{periodsmall}{FE52} \pdfglyphtounicode{periodsuperior}{002E} \pdfglyphtounicode{perispomenigreekcmb}{0342} \pdfglyphtounicode{perpcorrespond}{2A5E} \pdfglyphtounicode{perpendicular}{22A5} \pdfglyphtounicode{pertenthousand}{2031} \pdfglyphtounicode{perthousand}{2030} \pdfglyphtounicode{peseta}{20A7} \pdfglyphtounicode{pfsquare}{338A} \pdfglyphtounicode{phabengali}{09AB} \pdfglyphtounicode{phadeva}{092B} \pdfglyphtounicode{phagujarati}{0AAB} \pdfglyphtounicode{phagurmukhi}{0A2B} \pdfglyphtounicode{phi}{03C6} \pdfglyphtounicode{phi1}{03D5} \pdfglyphtounicode{phieuphacirclekorean}{327A} \pdfglyphtounicode{phieuphaparenkorean}{321A} \pdfglyphtounicode{phieuphcirclekorean}{326C} \pdfglyphtounicode{phieuphkorean}{314D} \pdfglyphtounicode{phieuphparenkorean}{320C} \pdfglyphtounicode{philatin}{0278} \pdfglyphtounicode{phinthuthai}{0E3A} \pdfglyphtounicode{phisymbolgreek}{03D5} \pdfglyphtounicode{phook}{01A5} \pdfglyphtounicode{phophanthai}{0E1E} \pdfglyphtounicode{phophungthai}{0E1C} \pdfglyphtounicode{phosamphaothai}{0E20} \pdfglyphtounicode{pi}{03C0} \pdfglyphtounicode{pi1}{03D6} \pdfglyphtounicode{pieupacirclekorean}{3273} \pdfglyphtounicode{pieupaparenkorean}{3213} \pdfglyphtounicode{pieupcieuckorean}{3176} \pdfglyphtounicode{pieupcirclekorean}{3265} \pdfglyphtounicode{pieupkiyeokkorean}{3172} \pdfglyphtounicode{pieupkorean}{3142} \pdfglyphtounicode{pieupparenkorean}{3205} \pdfglyphtounicode{pieupsioskiyeokkorean}{3174} \pdfglyphtounicode{pieupsioskorean}{3144} \pdfglyphtounicode{pieupsiostikeutkorean}{3175} \pdfglyphtounicode{pieupthieuthkorean}{3177} \pdfglyphtounicode{pieuptikeutkorean}{3173} \pdfglyphtounicode{pihiragana}{3074} \pdfglyphtounicode{pikatakana}{30D4} \pdfglyphtounicode{pisymbolgreek}{03D6} \pdfglyphtounicode{piwrarmenian}{0583} \pdfglyphtounicode{planckover2pi}{210F} \pdfglyphtounicode{planckover2pi1}{210F} \pdfglyphtounicode{plus}{002B} \pdfglyphtounicode{plusbelowcmb}{031F} \pdfglyphtounicode{pluscircle}{2295} \pdfglyphtounicode{plusminus}{00B1} \pdfglyphtounicode{plusmod}{02D6} \pdfglyphtounicode{plusmonospace}{FF0B} \pdfglyphtounicode{plussmall}{FE62} \pdfglyphtounicode{plussuperior}{207A} \pdfglyphtounicode{pmonospace}{FF50} \pdfglyphtounicode{pmsquare}{33D8} \pdfglyphtounicode{pohiragana}{307D} \pdfglyphtounicode{pointingindexdownwhite}{261F} \pdfglyphtounicode{pointingindexleftwhite}{261C} \pdfglyphtounicode{pointingindexrightwhite}{261E} \pdfglyphtounicode{pointingindexupwhite}{261D} \pdfglyphtounicode{pokatakana}{30DD} \pdfglyphtounicode{poplathai}{0E1B} \pdfglyphtounicode{postalmark}{3012} \pdfglyphtounicode{postalmarkface}{3020} \pdfglyphtounicode{pparen}{24AB} \pdfglyphtounicode{precedenotdbleqv}{2AB9} \pdfglyphtounicode{precedenotslnteql}{2AB5} \pdfglyphtounicode{precedeornoteqvlnt}{22E8} \pdfglyphtounicode{precedes}{227A} \pdfglyphtounicode{precedesequal}{2AAF} \pdfglyphtounicode{precedesorcurly}{227C} \pdfglyphtounicode{precedesorequal}{227E} \pdfglyphtounicode{prescription}{211E} \pdfglyphtounicode{prime}{2032} \pdfglyphtounicode{primemod}{02B9} \pdfglyphtounicode{primereverse}{2035} \pdfglyphtounicode{primereversed}{2035} \pdfglyphtounicode{product}{220F} \pdfglyphtounicode{projective}{2305} \pdfglyphtounicode{prolongedkana}{30FC} \pdfglyphtounicode{propellor}{2318} \pdfglyphtounicode{propersubset}{2282} \pdfglyphtounicode{propersuperset}{2283} \pdfglyphtounicode{proportion}{2237} \pdfglyphtounicode{proportional}{221D} \pdfglyphtounicode{psi}{03C8} \pdfglyphtounicode{psicyrillic}{0471} \pdfglyphtounicode{psilipneumatacyrilliccmb}{0486} \pdfglyphtounicode{pssquare}{33B0} \pdfglyphtounicode{puhiragana}{3077} \pdfglyphtounicode{pukatakana}{30D7} \pdfglyphtounicode{punctdash}{2014} \pdfglyphtounicode{pvsquare}{33B4} \pdfglyphtounicode{pwsquare}{33BA} \pdfglyphtounicode{q}{0071} \pdfglyphtounicode{qadeva}{0958} \pdfglyphtounicode{qadmahebrew}{05A8} \pdfglyphtounicode{qafarabic}{0642} \pdfglyphtounicode{qaffinalarabic}{FED6} \pdfglyphtounicode{qafinitialarabic}{FED7} \pdfglyphtounicode{qafmedialarabic}{FED8} \pdfglyphtounicode{qamats}{05B8} \pdfglyphtounicode{qamats10}{05B8} \pdfglyphtounicode{qamats1a}{05B8} \pdfglyphtounicode{qamats1c}{05B8} \pdfglyphtounicode{qamats27}{05B8} \pdfglyphtounicode{qamats29}{05B8} \pdfglyphtounicode{qamats33}{05B8} \pdfglyphtounicode{qamatsde}{05B8} \pdfglyphtounicode{qamatshebrew}{05B8} \pdfglyphtounicode{qamatsnarrowhebrew}{05B8} \pdfglyphtounicode{qamatsqatanhebrew}{05B8} \pdfglyphtounicode{qamatsqatannarrowhebrew}{05B8} \pdfglyphtounicode{qamatsqatanquarterhebrew}{05B8} \pdfglyphtounicode{qamatsqatanwidehebrew}{05B8} \pdfglyphtounicode{qamatsquarterhebrew}{05B8} \pdfglyphtounicode{qamatswidehebrew}{05B8} \pdfglyphtounicode{qarneyparahebrew}{059F} \pdfglyphtounicode{qbopomofo}{3111} \pdfglyphtounicode{qcircle}{24E0} \pdfglyphtounicode{qhook}{02A0} \pdfglyphtounicode{qmonospace}{FF51} \pdfglyphtounicode{qof}{05E7} \pdfglyphtounicode{qofdagesh}{FB47} \pdfglyphtounicode{qofdageshhebrew}{FB47} \pdfglyphtounicode{qofhatafpatah}{05E7 05B2} \pdfglyphtounicode{qofhatafpatahhebrew}{05E7 05B2} \pdfglyphtounicode{qofhatafsegol}{05E7 05B1} \pdfglyphtounicode{qofhatafsegolhebrew}{05E7 05B1} \pdfglyphtounicode{qofhebrew}{05E7} \pdfglyphtounicode{qofhiriq}{05E7 05B4} \pdfglyphtounicode{qofhiriqhebrew}{05E7 05B4} \pdfglyphtounicode{qofholam}{05E7 05B9} \pdfglyphtounicode{qofholamhebrew}{05E7 05B9} \pdfglyphtounicode{qofpatah}{05E7 05B7} \pdfglyphtounicode{qofpatahhebrew}{05E7 05B7} \pdfglyphtounicode{qofqamats}{05E7 05B8} \pdfglyphtounicode{qofqamatshebrew}{05E7 05B8} \pdfglyphtounicode{qofqubuts}{05E7 05BB} \pdfglyphtounicode{qofqubutshebrew}{05E7 05BB} \pdfglyphtounicode{qofsegol}{05E7 05B6} \pdfglyphtounicode{qofsegolhebrew}{05E7 05B6} \pdfglyphtounicode{qofsheva}{05E7 05B0} \pdfglyphtounicode{qofshevahebrew}{05E7 05B0} \pdfglyphtounicode{qoftsere}{05E7 05B5} \pdfglyphtounicode{qoftserehebrew}{05E7 05B5} \pdfglyphtounicode{qparen}{24AC} \pdfglyphtounicode{quarternote}{2669} \pdfglyphtounicode{qubuts}{05BB} \pdfglyphtounicode{qubuts18}{05BB} \pdfglyphtounicode{qubuts25}{05BB} \pdfglyphtounicode{qubuts31}{05BB} \pdfglyphtounicode{qubutshebrew}{05BB} \pdfglyphtounicode{qubutsnarrowhebrew}{05BB} \pdfglyphtounicode{qubutsquarterhebrew}{05BB} \pdfglyphtounicode{qubutswidehebrew}{05BB} \pdfglyphtounicode{question}{003F} \pdfglyphtounicode{questionarabic}{061F} \pdfglyphtounicode{questionarmenian}{055E} \pdfglyphtounicode{questiondown}{00BF} \pdfglyphtounicode{questiondownsmall}{00BF} \pdfglyphtounicode{questiongreek}{037E} \pdfglyphtounicode{questionmonospace}{FF1F} \pdfglyphtounicode{questionsmall}{003F} \pdfglyphtounicode{quotedbl}{0022} \pdfglyphtounicode{quotedblbase}{201E} \pdfglyphtounicode{quotedblleft}{201C} \pdfglyphtounicode{quotedblmonospace}{FF02} \pdfglyphtounicode{quotedblprime}{301E} \pdfglyphtounicode{quotedblprimereversed}{301D} \pdfglyphtounicode{quotedblright}{201D} \pdfglyphtounicode{quoteleft}{2018} \pdfglyphtounicode{quoteleftreversed}{201B} \pdfglyphtounicode{quotereversed}{201B} \pdfglyphtounicode{quoteright}{2019} \pdfglyphtounicode{quoterightn}{0149} \pdfglyphtounicode{quotesinglbase}{201A} \pdfglyphtounicode{quotesingle}{0027} \pdfglyphtounicode{quotesinglemonospace}{FF07} \pdfglyphtounicode{r}{0072} \pdfglyphtounicode{raarmenian}{057C} \pdfglyphtounicode{rabengali}{09B0} \pdfglyphtounicode{racute}{0155} \pdfglyphtounicode{radeva}{0930} \pdfglyphtounicode{radical}{221A} \pdfglyphtounicode{radicalex}{F8E5} \pdfglyphtounicode{radoverssquare}{33AE} \pdfglyphtounicode{radoverssquaredsquare}{33AF} \pdfglyphtounicode{radsquare}{33AD} \pdfglyphtounicode{rafe}{05BF} \pdfglyphtounicode{rafehebrew}{05BF} \pdfglyphtounicode{ragujarati}{0AB0} \pdfglyphtounicode{ragurmukhi}{0A30} \pdfglyphtounicode{rahiragana}{3089} \pdfglyphtounicode{rakatakana}{30E9} \pdfglyphtounicode{rakatakanahalfwidth}{FF97} \pdfglyphtounicode{ralowerdiagonalbengali}{09F1} \pdfglyphtounicode{ramiddlediagonalbengali}{09F0} \pdfglyphtounicode{ramshorn}{0264} \pdfglyphtounicode{rangedash}{2013} \pdfglyphtounicode{ratio}{2236} \pdfglyphtounicode{rbopomofo}{3116} \pdfglyphtounicode{rcaron}{0159} \pdfglyphtounicode{rcedilla}{0157} \pdfglyphtounicode{rcircle}{24E1} \pdfglyphtounicode{rcommaaccent}{0157} \pdfglyphtounicode{rdblgrave}{0211} \pdfglyphtounicode{rdotaccent}{1E59} \pdfglyphtounicode{rdotbelow}{1E5B} \pdfglyphtounicode{rdotbelowmacron}{1E5D} \pdfglyphtounicode{referencemark}{203B} \pdfglyphtounicode{reflexsubset}{2286} \pdfglyphtounicode{reflexsuperset}{2287} \pdfglyphtounicode{registered}{00AE} \pdfglyphtounicode{registersans}{00AE} \pdfglyphtounicode{registerserif}{00AE} \pdfglyphtounicode{reharabic}{0631} \pdfglyphtounicode{reharmenian}{0580} \pdfglyphtounicode{rehfinalarabic}{FEAE} \pdfglyphtounicode{rehiragana}{308C} \pdfglyphtounicode{rehyehaleflamarabic}{0631 FEF3 FE8E 0644} \pdfglyphtounicode{rekatakana}{30EC} \pdfglyphtounicode{rekatakanahalfwidth}{FF9A} \pdfglyphtounicode{resh}{05E8} \pdfglyphtounicode{reshdageshhebrew}{FB48} \pdfglyphtounicode{reshhatafpatah}{05E8 05B2} \pdfglyphtounicode{reshhatafpatahhebrew}{05E8 05B2} \pdfglyphtounicode{reshhatafsegol}{05E8 05B1} \pdfglyphtounicode{reshhatafsegolhebrew}{05E8 05B1} \pdfglyphtounicode{reshhebrew}{05E8} \pdfglyphtounicode{reshhiriq}{05E8 05B4} \pdfglyphtounicode{reshhiriqhebrew}{05E8 05B4} \pdfglyphtounicode{reshholam}{05E8 05B9} \pdfglyphtounicode{reshholamhebrew}{05E8 05B9} \pdfglyphtounicode{reshpatah}{05E8 05B7} \pdfglyphtounicode{reshpatahhebrew}{05E8 05B7} \pdfglyphtounicode{reshqamats}{05E8 05B8} \pdfglyphtounicode{reshqamatshebrew}{05E8 05B8} \pdfglyphtounicode{reshqubuts}{05E8 05BB} \pdfglyphtounicode{reshqubutshebrew}{05E8 05BB} \pdfglyphtounicode{reshsegol}{05E8 05B6} \pdfglyphtounicode{reshsegolhebrew}{05E8 05B6} \pdfglyphtounicode{reshsheva}{05E8 05B0} \pdfglyphtounicode{reshshevahebrew}{05E8 05B0} \pdfglyphtounicode{reshtsere}{05E8 05B5} \pdfglyphtounicode{reshtserehebrew}{05E8 05B5} \pdfglyphtounicode{revasymptequal}{22CD} \pdfglyphtounicode{reversedtilde}{223D} \pdfglyphtounicode{reviahebrew}{0597} \pdfglyphtounicode{reviamugrashhebrew}{0597} \pdfglyphtounicode{revlogicalnot}{2310} \pdfglyphtounicode{revsimilar}{223D} \pdfglyphtounicode{rfishhook}{027E} \pdfglyphtounicode{rfishhookreversed}{027F} \pdfglyphtounicode{rhabengali}{09DD} \pdfglyphtounicode{rhadeva}{095D} \pdfglyphtounicode{rho}{03C1} \pdfglyphtounicode{rho1}{03F1} \pdfglyphtounicode{rhook}{027D} \pdfglyphtounicode{rhookturned}{027B} \pdfglyphtounicode{rhookturnedsuperior}{02B5} \pdfglyphtounicode{rhosymbolgreek}{03F1} \pdfglyphtounicode{rhotichookmod}{02DE} \pdfglyphtounicode{rieulacirclekorean}{3271} \pdfglyphtounicode{rieulaparenkorean}{3211} \pdfglyphtounicode{rieulcirclekorean}{3263} \pdfglyphtounicode{rieulhieuhkorean}{3140} \pdfglyphtounicode{rieulkiyeokkorean}{313A} \pdfglyphtounicode{rieulkiyeoksioskorean}{3169} \pdfglyphtounicode{rieulkorean}{3139} \pdfglyphtounicode{rieulmieumkorean}{313B} \pdfglyphtounicode{rieulpansioskorean}{316C} \pdfglyphtounicode{rieulparenkorean}{3203} \pdfglyphtounicode{rieulphieuphkorean}{313F} \pdfglyphtounicode{rieulpieupkorean}{313C} \pdfglyphtounicode{rieulpieupsioskorean}{316B} \pdfglyphtounicode{rieulsioskorean}{313D} \pdfglyphtounicode{rieulthieuthkorean}{313E} \pdfglyphtounicode{rieultikeutkorean}{316A} \pdfglyphtounicode{rieulyeorinhieuhkorean}{316D} \pdfglyphtounicode{rightangle}{221F} \pdfglyphtounicode{rightanglene}{231D} \pdfglyphtounicode{rightanglenw}{231C} \pdfglyphtounicode{rightanglese}{231F} \pdfglyphtounicode{rightanglesw}{231E} \pdfglyphtounicode{righttackbelowcmb}{0319} \pdfglyphtounicode{righttriangle}{22BF} \pdfglyphtounicode{rihiragana}{308A} \pdfglyphtounicode{rikatakana}{30EA} \pdfglyphtounicode{rikatakanahalfwidth}{FF98} \pdfglyphtounicode{ring}{02DA} \pdfglyphtounicode{ringbelowcmb}{0325} \pdfglyphtounicode{ringcmb}{030A} \pdfglyphtounicode{ringhalfleft}{02BF} \pdfglyphtounicode{ringhalfleftarmenian}{0559} \pdfglyphtounicode{ringhalfleftbelowcmb}{031C} \pdfglyphtounicode{ringhalfleftcentered}{02D3} \pdfglyphtounicode{ringhalfright}{02BE} \pdfglyphtounicode{ringhalfrightbelowcmb}{0339} \pdfglyphtounicode{ringhalfrightcentered}{02D2} \pdfglyphtounicode{ringinequal}{2256} \pdfglyphtounicode{rinvertedbreve}{0213} \pdfglyphtounicode{rittorusquare}{3351} \pdfglyphtounicode{rlinebelow}{1E5F} \pdfglyphtounicode{rlongleg}{027C} \pdfglyphtounicode{rlonglegturned}{027A} \pdfglyphtounicode{rmonospace}{FF52} \pdfglyphtounicode{rohiragana}{308D} \pdfglyphtounicode{rokatakana}{30ED} \pdfglyphtounicode{rokatakanahalfwidth}{FF9B} \pdfglyphtounicode{roruathai}{0E23} \pdfglyphtounicode{rparen}{24AD} \pdfglyphtounicode{rrabengali}{09DC} \pdfglyphtounicode{rradeva}{0931} \pdfglyphtounicode{rragurmukhi}{0A5C} \pdfglyphtounicode{rreharabic}{0691} \pdfglyphtounicode{rrehfinalarabic}{FB8D} \pdfglyphtounicode{rrvocalicbengali}{09E0} \pdfglyphtounicode{rrvocalicdeva}{0960} \pdfglyphtounicode{rrvocalicgujarati}{0AE0} \pdfglyphtounicode{rrvocalicvowelsignbengali}{09C4} \pdfglyphtounicode{rrvocalicvowelsigndeva}{0944} \pdfglyphtounicode{rrvocalicvowelsigngujarati}{0AC4} \pdfglyphtounicode{rsuperior}{0072} \pdfglyphtounicode{rtblock}{2590} \pdfglyphtounicode{rturned}{0279} \pdfglyphtounicode{rturnedsuperior}{02B4} \pdfglyphtounicode{ruhiragana}{308B} \pdfglyphtounicode{rukatakana}{30EB} \pdfglyphtounicode{rukatakanahalfwidth}{FF99} \pdfglyphtounicode{rupeemarkbengali}{09F2} \pdfglyphtounicode{rupeesignbengali}{09F3} \pdfglyphtounicode{rupiah}{20A8} \pdfglyphtounicode{ruthai}{0E24} \pdfglyphtounicode{rvocalicbengali}{098B} \pdfglyphtounicode{rvocalicdeva}{090B} \pdfglyphtounicode{rvocalicgujarati}{0A8B} \pdfglyphtounicode{rvocalicvowelsignbengali}{09C3} \pdfglyphtounicode{rvocalicvowelsigndeva}{0943} \pdfglyphtounicode{rvocalicvowelsigngujarati}{0AC3} \pdfglyphtounicode{s}{0073} \pdfglyphtounicode{sabengali}{09B8} \pdfglyphtounicode{sacute}{015B} \pdfglyphtounicode{sacutedotaccent}{1E65} \pdfglyphtounicode{sadarabic}{0635} \pdfglyphtounicode{sadeva}{0938} \pdfglyphtounicode{sadfinalarabic}{FEBA} \pdfglyphtounicode{sadinitialarabic}{FEBB} \pdfglyphtounicode{sadmedialarabic}{FEBC} \pdfglyphtounicode{sagujarati}{0AB8} \pdfglyphtounicode{sagurmukhi}{0A38} \pdfglyphtounicode{sahiragana}{3055} \pdfglyphtounicode{sakatakana}{30B5} \pdfglyphtounicode{sakatakanahalfwidth}{FF7B} \pdfglyphtounicode{sallallahoualayhewasallamarabic}{FDFA} \pdfglyphtounicode{samekh}{05E1} \pdfglyphtounicode{samekhdagesh}{FB41} \pdfglyphtounicode{samekhdageshhebrew}{FB41} \pdfglyphtounicode{samekhhebrew}{05E1} \pdfglyphtounicode{saraaathai}{0E32} \pdfglyphtounicode{saraaethai}{0E41} \pdfglyphtounicode{saraaimaimalaithai}{0E44} \pdfglyphtounicode{saraaimaimuanthai}{0E43} \pdfglyphtounicode{saraamthai}{0E33} \pdfglyphtounicode{saraathai}{0E30} \pdfglyphtounicode{saraethai}{0E40} \pdfglyphtounicode{saraiileftthai}{F886} \pdfglyphtounicode{saraiithai}{0E35} \pdfglyphtounicode{saraileftthai}{F885} \pdfglyphtounicode{saraithai}{0E34} \pdfglyphtounicode{saraothai}{0E42} \pdfglyphtounicode{saraueeleftthai}{F888} \pdfglyphtounicode{saraueethai}{0E37} \pdfglyphtounicode{saraueleftthai}{F887} \pdfglyphtounicode{sarauethai}{0E36} \pdfglyphtounicode{sarauthai}{0E38} \pdfglyphtounicode{sarauuthai}{0E39} \pdfglyphtounicode{satisfies}{22A8} \pdfglyphtounicode{sbopomofo}{3119} \pdfglyphtounicode{scaron}{0161} \pdfglyphtounicode{scarondotaccent}{1E67} \pdfglyphtounicode{scedilla}{015F} \pdfglyphtounicode{schwa}{0259} \pdfglyphtounicode{schwacyrillic}{04D9} \pdfglyphtounicode{schwadieresiscyrillic}{04DB} \pdfglyphtounicode{schwahook}{025A} \pdfglyphtounicode{scircle}{24E2} \pdfglyphtounicode{scircumflex}{015D} \pdfglyphtounicode{scommaaccent}{0219} \pdfglyphtounicode{sdotaccent}{1E61} \pdfglyphtounicode{sdotbelow}{1E63} \pdfglyphtounicode{sdotbelowdotaccent}{1E69} \pdfglyphtounicode{seagullbelowcmb}{033C} \pdfglyphtounicode{second}{2033} \pdfglyphtounicode{secondtonechinese}{02CA} \pdfglyphtounicode{section}{00A7} \pdfglyphtounicode{seenarabic}{0633} \pdfglyphtounicode{seenfinalarabic}{FEB2} \pdfglyphtounicode{seeninitialarabic}{FEB3} \pdfglyphtounicode{seenmedialarabic}{FEB4} \pdfglyphtounicode{segol}{05B6} \pdfglyphtounicode{segol13}{05B6} \pdfglyphtounicode{segol1f}{05B6} \pdfglyphtounicode{segol2c}{05B6} \pdfglyphtounicode{segolhebrew}{05B6} \pdfglyphtounicode{segolnarrowhebrew}{05B6} \pdfglyphtounicode{segolquarterhebrew}{05B6} \pdfglyphtounicode{segoltahebrew}{0592} \pdfglyphtounicode{segolwidehebrew}{05B6} \pdfglyphtounicode{seharmenian}{057D} \pdfglyphtounicode{sehiragana}{305B} \pdfglyphtounicode{sekatakana}{30BB} \pdfglyphtounicode{sekatakanahalfwidth}{FF7E} \pdfglyphtounicode{semicolon}{003B} \pdfglyphtounicode{semicolonarabic}{061B} \pdfglyphtounicode{semicolonmonospace}{FF1B} \pdfglyphtounicode{semicolonsmall}{FE54} \pdfglyphtounicode{semivoicedmarkkana}{309C} \pdfglyphtounicode{semivoicedmarkkanahalfwidth}{FF9F} \pdfglyphtounicode{sentisquare}{3322} \pdfglyphtounicode{sentosquare}{3323} \pdfglyphtounicode{seven}{0037} \pdfglyphtounicode{sevenarabic}{0667} \pdfglyphtounicode{sevenbengali}{09ED} \pdfglyphtounicode{sevencircle}{2466} \pdfglyphtounicode{sevencircleinversesansserif}{2790} \pdfglyphtounicode{sevendeva}{096D} \pdfglyphtounicode{seveneighths}{215E} \pdfglyphtounicode{sevengujarati}{0AED} \pdfglyphtounicode{sevengurmukhi}{0A6D} \pdfglyphtounicode{sevenhackarabic}{0667} \pdfglyphtounicode{sevenhangzhou}{3027} \pdfglyphtounicode{sevenideographicparen}{3226} \pdfglyphtounicode{seveninferior}{2087} \pdfglyphtounicode{sevenmonospace}{FF17} \pdfglyphtounicode{sevenoldstyle}{0037} \pdfglyphtounicode{sevenparen}{247A} \pdfglyphtounicode{sevenperiod}{248E} \pdfglyphtounicode{sevenpersian}{06F7} \pdfglyphtounicode{sevenroman}{2176} \pdfglyphtounicode{sevensuperior}{2077} \pdfglyphtounicode{seventeencircle}{2470} \pdfglyphtounicode{seventeenparen}{2484} \pdfglyphtounicode{seventeenperiod}{2498} \pdfglyphtounicode{seventhai}{0E57} \pdfglyphtounicode{sfthyphen}{00AD} \pdfglyphtounicode{shaarmenian}{0577} \pdfglyphtounicode{shabengali}{09B6} \pdfglyphtounicode{shacyrillic}{0448} \pdfglyphtounicode{shaddaarabic}{0651} \pdfglyphtounicode{shaddadammaarabic}{FC61} \pdfglyphtounicode{shaddadammatanarabic}{FC5E} \pdfglyphtounicode{shaddafathaarabic}{FC60} \pdfglyphtounicode{shaddafathatanarabic}{0651 064B} \pdfglyphtounicode{shaddakasraarabic}{FC62} \pdfglyphtounicode{shaddakasratanarabic}{FC5F} \pdfglyphtounicode{shade}{2592} \pdfglyphtounicode{shadedark}{2593} \pdfglyphtounicode{shadelight}{2591} \pdfglyphtounicode{shademedium}{2592} \pdfglyphtounicode{shadeva}{0936} \pdfglyphtounicode{shagujarati}{0AB6} \pdfglyphtounicode{shagurmukhi}{0A36} \pdfglyphtounicode{shalshelethebrew}{0593} \pdfglyphtounicode{sharp}{266F} \pdfglyphtounicode{shbopomofo}{3115} \pdfglyphtounicode{shchacyrillic}{0449} \pdfglyphtounicode{sheenarabic}{0634} \pdfglyphtounicode{sheenfinalarabic}{FEB6} \pdfglyphtounicode{sheeninitialarabic}{FEB7} \pdfglyphtounicode{sheenmedialarabic}{FEB8} \pdfglyphtounicode{sheicoptic}{03E3} \pdfglyphtounicode{sheqel}{20AA} \pdfglyphtounicode{sheqelhebrew}{20AA} \pdfglyphtounicode{sheva}{05B0} \pdfglyphtounicode{sheva115}{05B0} \pdfglyphtounicode{sheva15}{05B0} \pdfglyphtounicode{sheva22}{05B0} \pdfglyphtounicode{sheva2e}{05B0} \pdfglyphtounicode{shevahebrew}{05B0} \pdfglyphtounicode{shevanarrowhebrew}{05B0} \pdfglyphtounicode{shevaquarterhebrew}{05B0} \pdfglyphtounicode{shevawidehebrew}{05B0} \pdfglyphtounicode{shhacyrillic}{04BB} \pdfglyphtounicode{shiftleft}{21B0} \pdfglyphtounicode{shiftright}{21B1} \pdfglyphtounicode{shimacoptic}{03ED} \pdfglyphtounicode{shin}{05E9} \pdfglyphtounicode{shindagesh}{FB49} \pdfglyphtounicode{shindageshhebrew}{FB49} \pdfglyphtounicode{shindageshshindot}{FB2C} \pdfglyphtounicode{shindageshshindothebrew}{FB2C} \pdfglyphtounicode{shindageshsindot}{FB2D} \pdfglyphtounicode{shindageshsindothebrew}{FB2D} \pdfglyphtounicode{shindothebrew}{05C1} \pdfglyphtounicode{shinhebrew}{05E9} \pdfglyphtounicode{shinshindot}{FB2A} \pdfglyphtounicode{shinshindothebrew}{FB2A} \pdfglyphtounicode{shinsindot}{FB2B} \pdfglyphtounicode{shinsindothebrew}{FB2B} \pdfglyphtounicode{shook}{0282} \pdfglyphtounicode{sigma}{03C3} \pdfglyphtounicode{sigma1}{03C2} \pdfglyphtounicode{sigmafinal}{03C2} \pdfglyphtounicode{sigmalunatesymbolgreek}{03F2} \pdfglyphtounicode{sihiragana}{3057} \pdfglyphtounicode{sikatakana}{30B7} \pdfglyphtounicode{sikatakanahalfwidth}{FF7C} \pdfglyphtounicode{siluqhebrew}{05BD} \pdfglyphtounicode{siluqlefthebrew}{05BD} \pdfglyphtounicode{similar}{223C} \pdfglyphtounicode{similarequal}{2243} \pdfglyphtounicode{sindothebrew}{05C2} \pdfglyphtounicode{siosacirclekorean}{3274} \pdfglyphtounicode{siosaparenkorean}{3214} \pdfglyphtounicode{sioscieuckorean}{317E} \pdfglyphtounicode{sioscirclekorean}{3266} \pdfglyphtounicode{sioskiyeokkorean}{317A} \pdfglyphtounicode{sioskorean}{3145} \pdfglyphtounicode{siosnieunkorean}{317B} \pdfglyphtounicode{siosparenkorean}{3206} \pdfglyphtounicode{siospieupkorean}{317D} \pdfglyphtounicode{siostikeutkorean}{317C} \pdfglyphtounicode{six}{0036} \pdfglyphtounicode{sixarabic}{0666} \pdfglyphtounicode{sixbengali}{09EC} \pdfglyphtounicode{sixcircle}{2465} \pdfglyphtounicode{sixcircleinversesansserif}{278F} \pdfglyphtounicode{sixdeva}{096C} \pdfglyphtounicode{sixgujarati}{0AEC} \pdfglyphtounicode{sixgurmukhi}{0A6C} \pdfglyphtounicode{sixhackarabic}{0666} \pdfglyphtounicode{sixhangzhou}{3026} \pdfglyphtounicode{sixideographicparen}{3225} \pdfglyphtounicode{sixinferior}{2086} \pdfglyphtounicode{sixmonospace}{FF16} \pdfglyphtounicode{sixoldstyle}{0036} \pdfglyphtounicode{sixparen}{2479} \pdfglyphtounicode{sixperiod}{248D} \pdfglyphtounicode{sixpersian}{06F6} \pdfglyphtounicode{sixroman}{2175} \pdfglyphtounicode{sixsuperior}{2076} \pdfglyphtounicode{sixteencircle}{246F} \pdfglyphtounicode{sixteencurrencydenominatorbengali}{09F9} \pdfglyphtounicode{sixteenparen}{2483} \pdfglyphtounicode{sixteenperiod}{2497} \pdfglyphtounicode{sixthai}{0E56} \pdfglyphtounicode{slash}{002F} \pdfglyphtounicode{slashmonospace}{FF0F} \pdfglyphtounicode{slong}{017F} \pdfglyphtounicode{slongdotaccent}{1E9B} \pdfglyphtounicode{slurabove}{2322} \pdfglyphtounicode{slurbelow}{2323} \pdfglyphtounicode{smile}{2323} \pdfglyphtounicode{smileface}{263A} \pdfglyphtounicode{smonospace}{FF53} \pdfglyphtounicode{sofpasuqhebrew}{05C3} \pdfglyphtounicode{softhyphen}{00AD} \pdfglyphtounicode{softsigncyrillic}{044C} \pdfglyphtounicode{sohiragana}{305D} \pdfglyphtounicode{sokatakana}{30BD} \pdfglyphtounicode{sokatakanahalfwidth}{FF7F} \pdfglyphtounicode{soliduslongoverlaycmb}{0338} \pdfglyphtounicode{solidusshortoverlaycmb}{0337} \pdfglyphtounicode{sorusithai}{0E29} \pdfglyphtounicode{sosalathai}{0E28} \pdfglyphtounicode{sosothai}{0E0B} \pdfglyphtounicode{sosuathai}{0E2A} \pdfglyphtounicode{space}{0020} \pdfglyphtounicode{spacehackarabic}{0020} \pdfglyphtounicode{spade}{2660} \pdfglyphtounicode{spadesuitblack}{2660} \pdfglyphtounicode{spadesuitwhite}{2664} \pdfglyphtounicode{sparen}{24AE} \pdfglyphtounicode{sphericalangle}{2222} \pdfglyphtounicode{square}{25A1} \pdfglyphtounicode{squarebelowcmb}{033B} \pdfglyphtounicode{squarecc}{33C4} \pdfglyphtounicode{squarecm}{339D} \pdfglyphtounicode{squarediagonalcrosshatchfill}{25A9} \pdfglyphtounicode{squaredot}{22A1} \pdfglyphtounicode{squarehorizontalfill}{25A4} \pdfglyphtounicode{squareimage}{228F} \pdfglyphtounicode{squarekg}{338F} \pdfglyphtounicode{squarekm}{339E} \pdfglyphtounicode{squarekmcapital}{33CE} \pdfglyphtounicode{squareln}{33D1} \pdfglyphtounicode{squarelog}{33D2} \pdfglyphtounicode{squaremg}{338E} \pdfglyphtounicode{squaremil}{33D5} \pdfglyphtounicode{squareminus}{229F} \pdfglyphtounicode{squaremm}{339C} \pdfglyphtounicode{squaremsquared}{33A1} \pdfglyphtounicode{squaremultiply}{22A0} \pdfglyphtounicode{squareoriginal}{2290} \pdfglyphtounicode{squareorthogonalcrosshatchfill}{25A6} \pdfglyphtounicode{squareplus}{229E} \pdfglyphtounicode{squaresolid}{25A0} \pdfglyphtounicode{squareupperlefttolowerrightfill}{25A7} \pdfglyphtounicode{squareupperrighttolowerleftfill}{25A8} \pdfglyphtounicode{squareverticalfill}{25A5} \pdfglyphtounicode{squarewhitewithsmallblack}{25A3} \pdfglyphtounicode{squiggleleftright}{21AD} \pdfglyphtounicode{squiggleright}{21DD} \pdfglyphtounicode{srsquare}{33DB} \pdfglyphtounicode{ssabengali}{09B7} \pdfglyphtounicode{ssadeva}{0937} \pdfglyphtounicode{ssagujarati}{0AB7} \pdfglyphtounicode{ssangcieuckorean}{3149} \pdfglyphtounicode{ssanghieuhkorean}{3185} \pdfglyphtounicode{ssangieungkorean}{3180} \pdfglyphtounicode{ssangkiyeokkorean}{3132} \pdfglyphtounicode{ssangnieunkorean}{3165} \pdfglyphtounicode{ssangpieupkorean}{3143} \pdfglyphtounicode{ssangsioskorean}{3146} \pdfglyphtounicode{ssangtikeutkorean}{3138} \pdfglyphtounicode{ssuperior}{0073} \pdfglyphtounicode{st}{0073 0074} \pdfglyphtounicode{star}{22C6} \pdfglyphtounicode{sterling}{00A3} \pdfglyphtounicode{sterlingmonospace}{FFE1} \pdfglyphtounicode{strokelongoverlaycmb}{0336} \pdfglyphtounicode{strokeshortoverlaycmb}{0335} \pdfglyphtounicode{subset}{2282} \pdfglyphtounicode{subsetdbl}{22D0} \pdfglyphtounicode{subsetdblequal}{2AC5} \pdfglyphtounicode{subsetnoteql}{228A} \pdfglyphtounicode{subsetnotequal}{228A} \pdfglyphtounicode{subsetorequal}{2286} \pdfglyphtounicode{subsetornotdbleql}{2ACB} \pdfglyphtounicode{subsetsqequal}{2291} \pdfglyphtounicode{succeeds}{227B} \pdfglyphtounicode{suchthat}{220B} \pdfglyphtounicode{suhiragana}{3059} \pdfglyphtounicode{sukatakana}{30B9} \pdfglyphtounicode{sukatakanahalfwidth}{FF7D} \pdfglyphtounicode{sukunarabic}{0652} \pdfglyphtounicode{summation}{2211} \pdfglyphtounicode{sun}{263C} \pdfglyphtounicode{superset}{2283} \pdfglyphtounicode{supersetdbl}{22D1} \pdfglyphtounicode{supersetdblequal}{2AC6} \pdfglyphtounicode{supersetnoteql}{228B} \pdfglyphtounicode{supersetnotequal}{228B} \pdfglyphtounicode{supersetorequal}{2287} \pdfglyphtounicode{supersetornotdbleql}{2ACC} \pdfglyphtounicode{supersetsqequal}{2292} \pdfglyphtounicode{svsquare}{33DC} \pdfglyphtounicode{syouwaerasquare}{337C} \pdfglyphtounicode{t}{0074} \pdfglyphtounicode{tabengali}{09A4} \pdfglyphtounicode{tackdown}{22A4} \pdfglyphtounicode{tackleft}{22A3} \pdfglyphtounicode{tadeva}{0924} \pdfglyphtounicode{tagujarati}{0AA4} \pdfglyphtounicode{tagurmukhi}{0A24} \pdfglyphtounicode{taharabic}{0637} \pdfglyphtounicode{tahfinalarabic}{FEC2} \pdfglyphtounicode{tahinitialarabic}{FEC3} \pdfglyphtounicode{tahiragana}{305F} \pdfglyphtounicode{tahmedialarabic}{FEC4} \pdfglyphtounicode{taisyouerasquare}{337D} \pdfglyphtounicode{takatakana}{30BF} \pdfglyphtounicode{takatakanahalfwidth}{FF80} \pdfglyphtounicode{tatweelarabic}{0640} \pdfglyphtounicode{tau}{03C4} \pdfglyphtounicode{tav}{05EA} \pdfglyphtounicode{tavdages}{FB4A} \pdfglyphtounicode{tavdagesh}{FB4A} \pdfglyphtounicode{tavdageshhebrew}{FB4A} \pdfglyphtounicode{tavhebrew}{05EA} \pdfglyphtounicode{tbar}{0167} \pdfglyphtounicode{tbopomofo}{310A} \pdfglyphtounicode{tcaron}{0165} \pdfglyphtounicode{tccurl}{02A8} \pdfglyphtounicode{tcedilla}{0163} \pdfglyphtounicode{tcheharabic}{0686} \pdfglyphtounicode{tchehfinalarabic}{FB7B} \pdfglyphtounicode{tchehinitialarabic}{FB7C} \pdfglyphtounicode{tchehmedialarabic}{FB7D} \pdfglyphtounicode{tchehmeeminitialarabic}{FB7C FEE4} \pdfglyphtounicode{tcircle}{24E3} \pdfglyphtounicode{tcircumflexbelow}{1E71} \pdfglyphtounicode{tcommaaccent}{0163} \pdfglyphtounicode{tdieresis}{1E97} \pdfglyphtounicode{tdotaccent}{1E6B} \pdfglyphtounicode{tdotbelow}{1E6D} \pdfglyphtounicode{tecyrillic}{0442} \pdfglyphtounicode{tedescendercyrillic}{04AD} \pdfglyphtounicode{teharabic}{062A} \pdfglyphtounicode{tehfinalarabic}{FE96} \pdfglyphtounicode{tehhahinitialarabic}{FCA2} \pdfglyphtounicode{tehhahisolatedarabic}{FC0C} \pdfglyphtounicode{tehinitialarabic}{FE97} \pdfglyphtounicode{tehiragana}{3066} \pdfglyphtounicode{tehjeeminitialarabic}{FCA1} \pdfglyphtounicode{tehjeemisolatedarabic}{FC0B} \pdfglyphtounicode{tehmarbutaarabic}{0629} \pdfglyphtounicode{tehmarbutafinalarabic}{FE94} \pdfglyphtounicode{tehmedialarabic}{FE98} \pdfglyphtounicode{tehmeeminitialarabic}{FCA4} \pdfglyphtounicode{tehmeemisolatedarabic}{FC0E} \pdfglyphtounicode{tehnoonfinalarabic}{FC73} \pdfglyphtounicode{tekatakana}{30C6} \pdfglyphtounicode{tekatakanahalfwidth}{FF83} \pdfglyphtounicode{telephone}{2121} \pdfglyphtounicode{telephoneblack}{260E} \pdfglyphtounicode{telishagedolahebrew}{05A0} \pdfglyphtounicode{telishaqetanahebrew}{05A9} \pdfglyphtounicode{tencircle}{2469} \pdfglyphtounicode{tenideographicparen}{3229} \pdfglyphtounicode{tenparen}{247D} \pdfglyphtounicode{tenperiod}{2491} \pdfglyphtounicode{tenroman}{2179} \pdfglyphtounicode{tesh}{02A7} \pdfglyphtounicode{tet}{05D8} \pdfglyphtounicode{tetdagesh}{FB38} \pdfglyphtounicode{tetdageshhebrew}{FB38} \pdfglyphtounicode{tethebrew}{05D8} \pdfglyphtounicode{tetsecyrillic}{04B5} \pdfglyphtounicode{tevirhebrew}{059B} \pdfglyphtounicode{tevirlefthebrew}{059B} \pdfglyphtounicode{tfm:cmbsy10/diamond}{2662} \pdfglyphtounicode{tfm:cmbsy10/heart}{2661} \pdfglyphtounicode{tfm:cmbsy5/diamond}{2662} \pdfglyphtounicode{tfm:cmbsy5/heart}{2661} \pdfglyphtounicode{tfm:cmbsy6/diamond}{2662} \pdfglyphtounicode{tfm:cmbsy6/heart}{2661} \pdfglyphtounicode{tfm:cmbsy7/diamond}{2662} \pdfglyphtounicode{tfm:cmbsy7/heart}{2661} \pdfglyphtounicode{tfm:cmbsy8/diamond}{2662} \pdfglyphtounicode{tfm:cmbsy8/heart}{2661} \pdfglyphtounicode{tfm:cmbsy9/diamond}{2662} \pdfglyphtounicode{tfm:cmbsy9/heart}{2661} \pdfglyphtounicode{tfm:cmmi10/phi}{03D5} \pdfglyphtounicode{tfm:cmmi10/phi1}{03C6} \pdfglyphtounicode{tfm:cmmi12/phi}{03D5} \pdfglyphtounicode{tfm:cmmi12/phi1}{03C6} \pdfglyphtounicode{tfm:cmmi5/phi}{03D5} \pdfglyphtounicode{tfm:cmmi5/phi1}{03C6} \pdfglyphtounicode{tfm:cmmi6/phi}{03D5} \pdfglyphtounicode{tfm:cmmi6/phi1}{03C6} \pdfglyphtounicode{tfm:cmmi7/phi}{03D5} \pdfglyphtounicode{tfm:cmmi7/phi1}{03C6} \pdfglyphtounicode{tfm:cmmi8/phi}{03D5} \pdfglyphtounicode{tfm:cmmi8/phi1}{03C6} \pdfglyphtounicode{tfm:cmmi9/phi}{03D5} \pdfglyphtounicode{tfm:cmmi9/phi1}{03C6} \pdfglyphtounicode{tfm:cmmib10/phi}{03D5} \pdfglyphtounicode{tfm:cmmib10/phi1}{03C6} \pdfglyphtounicode{tfm:cmmib5/phi}{03D5} \pdfglyphtounicode{tfm:cmmib5/phi1}{03C6} \pdfglyphtounicode{tfm:cmmib6/phi}{03D5} \pdfglyphtounicode{tfm:cmmib6/phi1}{03C6} \pdfglyphtounicode{tfm:cmmib7/phi}{03D5} \pdfglyphtounicode{tfm:cmmib7/phi1}{03C6} \pdfglyphtounicode{tfm:cmmib8/phi}{03D5} \pdfglyphtounicode{tfm:cmmib8/phi1}{03C6} \pdfglyphtounicode{tfm:cmmib9/phi}{03D5} \pdfglyphtounicode{tfm:cmmib9/phi1}{03C6} \pdfglyphtounicode{tfm:cmsy10/diamond}{2662} \pdfglyphtounicode{tfm:cmsy10/heart}{2661} \pdfglyphtounicode{tfm:cmsy5/heart}{2661} \pdfglyphtounicode{tfm:cmsy6/diamond}{2662} \pdfglyphtounicode{tfm:cmsy6/heart}{2661} \pdfglyphtounicode{tfm:cmsy7/diamond}{2662} \pdfglyphtounicode{tfm:cmsy7/heart}{2661} \pdfglyphtounicode{tfm:cmsy8/diamond}{2662} \pdfglyphtounicode{tfm:cmsy8/heart}{2661} \pdfglyphtounicode{tfm:cmsy9/diamond}{2662} \pdfglyphtounicode{tfm:cmsy9/heart}{2661} \pdfglyphtounicode{tfm:eurb10/phi}{03D5} \pdfglyphtounicode{tfm:eurb10/phi1}{03C6} \pdfglyphtounicode{tfm:eurb5/phi}{03D5} \pdfglyphtounicode{tfm:eurb5/phi1}{03C6} \pdfglyphtounicode{tfm:eurb6/phi}{03D5} \pdfglyphtounicode{tfm:eurb6/phi1}{03C6} \pdfglyphtounicode{tfm:eurb7/phi}{03D5} \pdfglyphtounicode{tfm:eurb7/phi1}{03C6} \pdfglyphtounicode{tfm:eurb8/phi}{03D5} \pdfglyphtounicode{tfm:eurb8/phi1}{03C6} \pdfglyphtounicode{tfm:eurb9/phi}{03D5} \pdfglyphtounicode{tfm:eurb9/phi1}{03C6} \pdfglyphtounicode{tfm:eurm10/phi}{03D5} \pdfglyphtounicode{tfm:eurm10/phi1}{03C6} \pdfglyphtounicode{tfm:eurm5/phi}{03D5} \pdfglyphtounicode{tfm:eurm5/phi1}{03C6} \pdfglyphtounicode{tfm:eurm6/phi}{03D5} \pdfglyphtounicode{tfm:eurm6/phi1}{03C6} \pdfglyphtounicode{tfm:eurm7/phi}{03D5} \pdfglyphtounicode{tfm:eurm7/phi1}{03C6} \pdfglyphtounicode{tfm:eurm8/phi}{03D5} \pdfglyphtounicode{tfm:eurm8/phi1}{03C6} \pdfglyphtounicode{tfm:eurm9/phi}{03D5} \pdfglyphtounicode{tfm:eurm9/phi1}{03C6} \pdfglyphtounicode{tfm:fplmbi/phi}{03D5} \pdfglyphtounicode{tfm:fplmbi/phi1}{03C6} \pdfglyphtounicode{tfm:fplmri/phi}{03D5} \pdfglyphtounicode{tfm:fplmri/phi1}{03C6} \pdfglyphtounicode{tfm:lmbsy10/diamond}{2662} \pdfglyphtounicode{tfm:lmbsy10/heart}{2661} \pdfglyphtounicode{tfm:lmbsy5/diamond}{2662} \pdfglyphtounicode{tfm:lmbsy5/heart}{2661} \pdfglyphtounicode{tfm:lmbsy7/diamond}{2662} \pdfglyphtounicode{tfm:lmbsy7/heart}{2661} \pdfglyphtounicode{tfm:lmmi10/phi}{03D5} \pdfglyphtounicode{tfm:lmmi10/phi1}{03C6} \pdfglyphtounicode{tfm:lmmi12/phi}{03D5} \pdfglyphtounicode{tfm:lmmi12/phi1}{03C6} \pdfglyphtounicode{tfm:lmmi5/phi}{03D5} \pdfglyphtounicode{tfm:lmmi5/phi1}{03C6} \pdfglyphtounicode{tfm:lmmi6/phi}{03D5} \pdfglyphtounicode{tfm:lmmi6/phi1}{03C6} \pdfglyphtounicode{tfm:lmmi7/phi}{03D5} \pdfglyphtounicode{tfm:lmmi7/phi1}{03C6} \pdfglyphtounicode{tfm:lmmi8/phi}{03D5} \pdfglyphtounicode{tfm:lmmi8/phi1}{03C6} \pdfglyphtounicode{tfm:lmmi9/phi}{03D5} \pdfglyphtounicode{tfm:lmmi9/phi1}{03C6} \pdfglyphtounicode{tfm:lmmib10/phi}{03D5} \pdfglyphtounicode{tfm:lmmib10/phi1}{03C6} \pdfglyphtounicode{tfm:lmmib5/phi}{03D5} \pdfglyphtounicode{tfm:lmmib5/phi1}{03C6} \pdfglyphtounicode{tfm:lmmib7/phi}{03D5} \pdfglyphtounicode{tfm:lmmib7/phi1}{03C6} \pdfglyphtounicode{tfm:lmsy10/diamond}{2662} \pdfglyphtounicode{tfm:lmsy10/heart}{2661} \pdfglyphtounicode{tfm:lmsy5/diamond}{2662} \pdfglyphtounicode{tfm:lmsy5/heart}{2661} \pdfglyphtounicode{tfm:lmsy6/diamond}{2662} \pdfglyphtounicode{tfm:lmsy6/heart}{2661} \pdfglyphtounicode{tfm:lmsy7/diamond}{2662} \pdfglyphtounicode{tfm:lmsy7/heart}{2661} \pdfglyphtounicode{tfm:lmsy8/diamond}{2662} \pdfglyphtounicode{tfm:lmsy8/heart}{2661} \pdfglyphtounicode{tfm:lmsy9/diamond}{2662} \pdfglyphtounicode{tfm:lmsy9/heart}{2661} \pdfglyphtounicode{tfm:msam10/diamond}{2662} \pdfglyphtounicode{tfm:msam5/diamond}{2662} \pdfglyphtounicode{tfm:msam6/diamond}{2662} \pdfglyphtounicode{tfm:msam7/diamond}{2662} \pdfglyphtounicode{tfm:msam8/diamond}{2662} \pdfglyphtounicode{tfm:msam9/diamond}{2662} \pdfglyphtounicode{tfm:pxbmia/phi}{03D5} \pdfglyphtounicode{tfm:pxbmia/phi1}{03C6} \pdfglyphtounicode{tfm:pxbsy/diamond}{2662} \pdfglyphtounicode{tfm:pxbsy/heart}{2661} \pdfglyphtounicode{tfm:pxbsya/diamond}{2662} \pdfglyphtounicode{tfm:pxmia/phi}{03D5} \pdfglyphtounicode{tfm:pxmia/phi1}{03C6} \pdfglyphtounicode{tfm:pxsy/diamond}{2662} \pdfglyphtounicode{tfm:pxsy/heart}{2661} \pdfglyphtounicode{tfm:pxsya/diamond}{2662} \pdfglyphtounicode{tfm:pzdr/a1}{2701} \pdfglyphtounicode{tfm:pzdr/a10}{2721} \pdfglyphtounicode{tfm:pzdr/a100}{275E} \pdfglyphtounicode{tfm:pzdr/a101}{2761} \pdfglyphtounicode{tfm:pzdr/a102}{2762} \pdfglyphtounicode{tfm:pzdr/a103}{2763} \pdfglyphtounicode{tfm:pzdr/a104}{2764} \pdfglyphtounicode{tfm:pzdr/a105}{2710} \pdfglyphtounicode{tfm:pzdr/a106}{2765} \pdfglyphtounicode{tfm:pzdr/a107}{2766} \pdfglyphtounicode{tfm:pzdr/a108}{2767} \pdfglyphtounicode{tfm:pzdr/a109}{2660} \pdfglyphtounicode{tfm:pzdr/a11}{261B} \pdfglyphtounicode{tfm:pzdr/a110}{2665} \pdfglyphtounicode{tfm:pzdr/a111}{2666} \pdfglyphtounicode{tfm:pzdr/a112}{2663} \pdfglyphtounicode{tfm:pzdr/a117}{2709} \pdfglyphtounicode{tfm:pzdr/a118}{2708} \pdfglyphtounicode{tfm:pzdr/a119}{2707} \pdfglyphtounicode{tfm:pzdr/a12}{261E} \pdfglyphtounicode{tfm:pzdr/a120}{2460} \pdfglyphtounicode{tfm:pzdr/a121}{2461} \pdfglyphtounicode{tfm:pzdr/a122}{2462} \pdfglyphtounicode{tfm:pzdr/a123}{2463} \pdfglyphtounicode{tfm:pzdr/a124}{2464} \pdfglyphtounicode{tfm:pzdr/a125}{2465} \pdfglyphtounicode{tfm:pzdr/a126}{2466} \pdfglyphtounicode{tfm:pzdr/a127}{2467} \pdfglyphtounicode{tfm:pzdr/a128}{2468} \pdfglyphtounicode{tfm:pzdr/a129}{2469} \pdfglyphtounicode{tfm:pzdr/a13}{270C} \pdfglyphtounicode{tfm:pzdr/a130}{2776} \pdfglyphtounicode{tfm:pzdr/a131}{2777} \pdfglyphtounicode{tfm:pzdr/a132}{2778} \pdfglyphtounicode{tfm:pzdr/a133}{2779} \pdfglyphtounicode{tfm:pzdr/a134}{277A} \pdfglyphtounicode{tfm:pzdr/a135}{277B} \pdfglyphtounicode{tfm:pzdr/a136}{277C} \pdfglyphtounicode{tfm:pzdr/a137}{277D} \pdfglyphtounicode{tfm:pzdr/a138}{277E} \pdfglyphtounicode{tfm:pzdr/a139}{277F} \pdfglyphtounicode{tfm:pzdr/a14}{270D} \pdfglyphtounicode{tfm:pzdr/a140}{2780} \pdfglyphtounicode{tfm:pzdr/a141}{2781} \pdfglyphtounicode{tfm:pzdr/a142}{2782} \pdfglyphtounicode{tfm:pzdr/a143}{2783} \pdfglyphtounicode{tfm:pzdr/a144}{2784} \pdfglyphtounicode{tfm:pzdr/a145}{2785} \pdfglyphtounicode{tfm:pzdr/a146}{2786} \pdfglyphtounicode{tfm:pzdr/a147}{2787} \pdfglyphtounicode{tfm:pzdr/a148}{2788} \pdfglyphtounicode{tfm:pzdr/a149}{2789} \pdfglyphtounicode{tfm:pzdr/a15}{270E} \pdfglyphtounicode{tfm:pzdr/a150}{278A} \pdfglyphtounicode{tfm:pzdr/a151}{278B} \pdfglyphtounicode{tfm:pzdr/a152}{278C} \pdfglyphtounicode{tfm:pzdr/a153}{278D} \pdfglyphtounicode{tfm:pzdr/a154}{278E} \pdfglyphtounicode{tfm:pzdr/a155}{278F} \pdfglyphtounicode{tfm:pzdr/a156}{2790} \pdfglyphtounicode{tfm:pzdr/a157}{2791} \pdfglyphtounicode{tfm:pzdr/a158}{2792} \pdfglyphtounicode{tfm:pzdr/a159}{2793} \pdfglyphtounicode{tfm:pzdr/a16}{270F} \pdfglyphtounicode{tfm:pzdr/a160}{2794} \pdfglyphtounicode{tfm:pzdr/a161}{2192} \pdfglyphtounicode{tfm:pzdr/a162}{27A3} \pdfglyphtounicode{tfm:pzdr/a163}{2194} \pdfglyphtounicode{tfm:pzdr/a164}{2195} \pdfglyphtounicode{tfm:pzdr/a165}{2799} \pdfglyphtounicode{tfm:pzdr/a166}{279B} \pdfglyphtounicode{tfm:pzdr/a167}{279C} \pdfglyphtounicode{tfm:pzdr/a168}{279D} \pdfglyphtounicode{tfm:pzdr/a169}{279E} \pdfglyphtounicode{tfm:pzdr/a17}{2711} \pdfglyphtounicode{tfm:pzdr/a170}{279F} \pdfglyphtounicode{tfm:pzdr/a171}{27A0} \pdfglyphtounicode{tfm:pzdr/a172}{27A1} \pdfglyphtounicode{tfm:pzdr/a173}{27A2} \pdfglyphtounicode{tfm:pzdr/a174}{27A4} \pdfglyphtounicode{tfm:pzdr/a175}{27A5} \pdfglyphtounicode{tfm:pzdr/a176}{27A6} \pdfglyphtounicode{tfm:pzdr/a177}{27A7} \pdfglyphtounicode{tfm:pzdr/a178}{27A8} \pdfglyphtounicode{tfm:pzdr/a179}{27A9} \pdfglyphtounicode{tfm:pzdr/a18}{2712} \pdfglyphtounicode{tfm:pzdr/a180}{27AB} \pdfglyphtounicode{tfm:pzdr/a181}{27AD} \pdfglyphtounicode{tfm:pzdr/a182}{27AF} \pdfglyphtounicode{tfm:pzdr/a183}{27B2} \pdfglyphtounicode{tfm:pzdr/a184}{27B3} \pdfglyphtounicode{tfm:pzdr/a185}{27B5} \pdfglyphtounicode{tfm:pzdr/a186}{27B8} \pdfglyphtounicode{tfm:pzdr/a187}{27BA} \pdfglyphtounicode{tfm:pzdr/a188}{27BB} \pdfglyphtounicode{tfm:pzdr/a189}{27BC} \pdfglyphtounicode{tfm:pzdr/a19}{2713} \pdfglyphtounicode{tfm:pzdr/a190}{27BD} \pdfglyphtounicode{tfm:pzdr/a191}{27BE} \pdfglyphtounicode{tfm:pzdr/a192}{279A} \pdfglyphtounicode{tfm:pzdr/a193}{27AA} \pdfglyphtounicode{tfm:pzdr/a194}{27B6} \pdfglyphtounicode{tfm:pzdr/a195}{27B9} \pdfglyphtounicode{tfm:pzdr/a196}{2798} \pdfglyphtounicode{tfm:pzdr/a197}{27B4} \pdfglyphtounicode{tfm:pzdr/a198}{27B7} \pdfglyphtounicode{tfm:pzdr/a199}{27AC} \pdfglyphtounicode{tfm:pzdr/a2}{2702} \pdfglyphtounicode{tfm:pzdr/a20}{2714} \pdfglyphtounicode{tfm:pzdr/a200}{27AE} \pdfglyphtounicode{tfm:pzdr/a201}{27B1} \pdfglyphtounicode{tfm:pzdr/a202}{2703} \pdfglyphtounicode{tfm:pzdr/a203}{2750} \pdfglyphtounicode{tfm:pzdr/a204}{2752} \pdfglyphtounicode{tfm:pzdr/a205}{276E} \pdfglyphtounicode{tfm:pzdr/a206}{2770} \pdfglyphtounicode{tfm:pzdr/a21}{2715} \pdfglyphtounicode{tfm:pzdr/a22}{2716} \pdfglyphtounicode{tfm:pzdr/a23}{2717} \pdfglyphtounicode{tfm:pzdr/a24}{2718} \pdfglyphtounicode{tfm:pzdr/a25}{2719} \pdfglyphtounicode{tfm:pzdr/a26}{271A} \pdfglyphtounicode{tfm:pzdr/a27}{271B} \pdfglyphtounicode{tfm:pzdr/a28}{271C} \pdfglyphtounicode{tfm:pzdr/a29}{2722} \pdfglyphtounicode{tfm:pzdr/a3}{2704} \pdfglyphtounicode{tfm:pzdr/a30}{2723} \pdfglyphtounicode{tfm:pzdr/a31}{2724} \pdfglyphtounicode{tfm:pzdr/a32}{2725} \pdfglyphtounicode{tfm:pzdr/a33}{2726} \pdfglyphtounicode{tfm:pzdr/a34}{2727} \pdfglyphtounicode{tfm:pzdr/a35}{2605} \pdfglyphtounicode{tfm:pzdr/a36}{2729} \pdfglyphtounicode{tfm:pzdr/a37}{272A} \pdfglyphtounicode{tfm:pzdr/a38}{272B} \pdfglyphtounicode{tfm:pzdr/a39}{272C} \pdfglyphtounicode{tfm:pzdr/a4}{260E} \pdfglyphtounicode{tfm:pzdr/a40}{272D} \pdfglyphtounicode{tfm:pzdr/a41}{272E} \pdfglyphtounicode{tfm:pzdr/a42}{272F} \pdfglyphtounicode{tfm:pzdr/a43}{2730} \pdfglyphtounicode{tfm:pzdr/a44}{2731} \pdfglyphtounicode{tfm:pzdr/a45}{2732} \pdfglyphtounicode{tfm:pzdr/a46}{2733} \pdfglyphtounicode{tfm:pzdr/a47}{2734} \pdfglyphtounicode{tfm:pzdr/a48}{2735} \pdfglyphtounicode{tfm:pzdr/a49}{2736} \pdfglyphtounicode{tfm:pzdr/a5}{2706} \pdfglyphtounicode{tfm:pzdr/a50}{2737} \pdfglyphtounicode{tfm:pzdr/a51}{2738} \pdfglyphtounicode{tfm:pzdr/a52}{2739} \pdfglyphtounicode{tfm:pzdr/a53}{273A} \pdfglyphtounicode{tfm:pzdr/a54}{273B} \pdfglyphtounicode{tfm:pzdr/a55}{273C} \pdfglyphtounicode{tfm:pzdr/a56}{273D} \pdfglyphtounicode{tfm:pzdr/a57}{273E} \pdfglyphtounicode{tfm:pzdr/a58}{273F} \pdfglyphtounicode{tfm:pzdr/a59}{2740} \pdfglyphtounicode{tfm:pzdr/a6}{271D} \pdfglyphtounicode{tfm:pzdr/a60}{2741} \pdfglyphtounicode{tfm:pzdr/a61}{2742} \pdfglyphtounicode{tfm:pzdr/a62}{2743} \pdfglyphtounicode{tfm:pzdr/a63}{2744} \pdfglyphtounicode{tfm:pzdr/a64}{2745} \pdfglyphtounicode{tfm:pzdr/a65}{2746} \pdfglyphtounicode{tfm:pzdr/a66}{2747} \pdfglyphtounicode{tfm:pzdr/a67}{2748} \pdfglyphtounicode{tfm:pzdr/a68}{2749} \pdfglyphtounicode{tfm:pzdr/a69}{274A} \pdfglyphtounicode{tfm:pzdr/a7}{271E} \pdfglyphtounicode{tfm:pzdr/a70}{274B} \pdfglyphtounicode{tfm:pzdr/a71}{25CF} \pdfglyphtounicode{tfm:pzdr/a72}{274D} \pdfglyphtounicode{tfm:pzdr/a73}{25A0} \pdfglyphtounicode{tfm:pzdr/a74}{274F} \pdfglyphtounicode{tfm:pzdr/a75}{2751} \pdfglyphtounicode{tfm:pzdr/a76}{25B2} \pdfglyphtounicode{tfm:pzdr/a77}{25BC} \pdfglyphtounicode{tfm:pzdr/a78}{25C6} \pdfglyphtounicode{tfm:pzdr/a79}{2756} \pdfglyphtounicode{tfm:pzdr/a8}{271F} \pdfglyphtounicode{tfm:pzdr/a81}{25D7} \pdfglyphtounicode{tfm:pzdr/a82}{2758} \pdfglyphtounicode{tfm:pzdr/a83}{2759} \pdfglyphtounicode{tfm:pzdr/a84}{275A} \pdfglyphtounicode{tfm:pzdr/a85}{276F} \pdfglyphtounicode{tfm:pzdr/a86}{2771} \pdfglyphtounicode{tfm:pzdr/a87}{2772} \pdfglyphtounicode{tfm:pzdr/a88}{2773} \pdfglyphtounicode{tfm:pzdr/a89}{2768} \pdfglyphtounicode{tfm:pzdr/a9}{2720} \pdfglyphtounicode{tfm:pzdr/a90}{2769} \pdfglyphtounicode{tfm:pzdr/a91}{276C} \pdfglyphtounicode{tfm:pzdr/a92}{276D} \pdfglyphtounicode{tfm:pzdr/a93}{276A} \pdfglyphtounicode{tfm:pzdr/a94}{276B} \pdfglyphtounicode{tfm:pzdr/a95}{2774} \pdfglyphtounicode{tfm:pzdr/a96}{2775} \pdfglyphtounicode{tfm:pzdr/a97}{275B} \pdfglyphtounicode{tfm:pzdr/a98}{275C} \pdfglyphtounicode{tfm:pzdr/a99}{275D} \pdfglyphtounicode{tfm:rpxbmi/phi}{03D5} \pdfglyphtounicode{tfm:rpxbmi/phi1}{03C6} \pdfglyphtounicode{tfm:rpxmi/phi}{03D5} \pdfglyphtounicode{tfm:rpxmi/phi1}{03C6} \pdfglyphtounicode{tfm:rpzdr/a1}{2701} \pdfglyphtounicode{tfm:rpzdr/a10}{2721} \pdfglyphtounicode{tfm:rpzdr/a100}{275E} \pdfglyphtounicode{tfm:rpzdr/a101}{2761} \pdfglyphtounicode{tfm:rpzdr/a102}{2762} \pdfglyphtounicode{tfm:rpzdr/a103}{2763} \pdfglyphtounicode{tfm:rpzdr/a104}{2764} \pdfglyphtounicode{tfm:rpzdr/a105}{2710} \pdfglyphtounicode{tfm:rpzdr/a106}{2765} \pdfglyphtounicode{tfm:rpzdr/a107}{2766} \pdfglyphtounicode{tfm:rpzdr/a108}{2767} \pdfglyphtounicode{tfm:rpzdr/a109}{2660} \pdfglyphtounicode{tfm:rpzdr/a11}{261B} \pdfglyphtounicode{tfm:rpzdr/a110}{2665} \pdfglyphtounicode{tfm:rpzdr/a111}{2666} \pdfglyphtounicode{tfm:rpzdr/a112}{2663} \pdfglyphtounicode{tfm:rpzdr/a117}{2709} \pdfglyphtounicode{tfm:rpzdr/a118}{2708} \pdfglyphtounicode{tfm:rpzdr/a119}{2707} \pdfglyphtounicode{tfm:rpzdr/a12}{261E} \pdfglyphtounicode{tfm:rpzdr/a120}{2460} \pdfglyphtounicode{tfm:rpzdr/a121}{2461} \pdfglyphtounicode{tfm:rpzdr/a122}{2462} \pdfglyphtounicode{tfm:rpzdr/a123}{2463} \pdfglyphtounicode{tfm:rpzdr/a124}{2464} \pdfglyphtounicode{tfm:rpzdr/a125}{2465} \pdfglyphtounicode{tfm:rpzdr/a126}{2466} \pdfglyphtounicode{tfm:rpzdr/a127}{2467} \pdfglyphtounicode{tfm:rpzdr/a128}{2468} \pdfglyphtounicode{tfm:rpzdr/a129}{2469} \pdfglyphtounicode{tfm:rpzdr/a13}{270C} \pdfglyphtounicode{tfm:rpzdr/a130}{2776} \pdfglyphtounicode{tfm:rpzdr/a131}{2777} \pdfglyphtounicode{tfm:rpzdr/a132}{2778} \pdfglyphtounicode{tfm:rpzdr/a133}{2779} \pdfglyphtounicode{tfm:rpzdr/a134}{277A} \pdfglyphtounicode{tfm:rpzdr/a135}{277B} \pdfglyphtounicode{tfm:rpzdr/a136}{277C} \pdfglyphtounicode{tfm:rpzdr/a137}{277D} \pdfglyphtounicode{tfm:rpzdr/a138}{277E} \pdfglyphtounicode{tfm:rpzdr/a139}{277F} \pdfglyphtounicode{tfm:rpzdr/a14}{270D} \pdfglyphtounicode{tfm:rpzdr/a140}{2780} \pdfglyphtounicode{tfm:rpzdr/a141}{2781} \pdfglyphtounicode{tfm:rpzdr/a142}{2782} \pdfglyphtounicode{tfm:rpzdr/a143}{2783} \pdfglyphtounicode{tfm:rpzdr/a144}{2784} \pdfglyphtounicode{tfm:rpzdr/a145}{2785} \pdfglyphtounicode{tfm:rpzdr/a146}{2786} \pdfglyphtounicode{tfm:rpzdr/a147}{2787} \pdfglyphtounicode{tfm:rpzdr/a148}{2788} \pdfglyphtounicode{tfm:rpzdr/a149}{2789} \pdfglyphtounicode{tfm:rpzdr/a15}{270E} \pdfglyphtounicode{tfm:rpzdr/a150}{278A} \pdfglyphtounicode{tfm:rpzdr/a151}{278B} \pdfglyphtounicode{tfm:rpzdr/a152}{278C} \pdfglyphtounicode{tfm:rpzdr/a153}{278D} \pdfglyphtounicode{tfm:rpzdr/a154}{278E} \pdfglyphtounicode{tfm:rpzdr/a155}{278F} \pdfglyphtounicode{tfm:rpzdr/a156}{2790} \pdfglyphtounicode{tfm:rpzdr/a157}{2791} \pdfglyphtounicode{tfm:rpzdr/a158}{2792} \pdfglyphtounicode{tfm:rpzdr/a159}{2793} \pdfglyphtounicode{tfm:rpzdr/a16}{270F} \pdfglyphtounicode{tfm:rpzdr/a160}{2794} \pdfglyphtounicode{tfm:rpzdr/a161}{2192} \pdfglyphtounicode{tfm:rpzdr/a162}{27A3} \pdfglyphtounicode{tfm:rpzdr/a163}{2194} \pdfglyphtounicode{tfm:rpzdr/a164}{2195} \pdfglyphtounicode{tfm:rpzdr/a165}{2799} \pdfglyphtounicode{tfm:rpzdr/a166}{279B} \pdfglyphtounicode{tfm:rpzdr/a167}{279C} \pdfglyphtounicode{tfm:rpzdr/a168}{279D} \pdfglyphtounicode{tfm:rpzdr/a169}{279E} \pdfglyphtounicode{tfm:rpzdr/a17}{2711} \pdfglyphtounicode{tfm:rpzdr/a170}{279F} \pdfglyphtounicode{tfm:rpzdr/a171}{27A0} \pdfglyphtounicode{tfm:rpzdr/a172}{27A1} \pdfglyphtounicode{tfm:rpzdr/a173}{27A2} \pdfglyphtounicode{tfm:rpzdr/a174}{27A4} \pdfglyphtounicode{tfm:rpzdr/a175}{27A5} \pdfglyphtounicode{tfm:rpzdr/a176}{27A6} \pdfglyphtounicode{tfm:rpzdr/a177}{27A7} \pdfglyphtounicode{tfm:rpzdr/a178}{27A8} \pdfglyphtounicode{tfm:rpzdr/a179}{27A9} \pdfglyphtounicode{tfm:rpzdr/a18}{2712} \pdfglyphtounicode{tfm:rpzdr/a180}{27AB} \pdfglyphtounicode{tfm:rpzdr/a181}{27AD} \pdfglyphtounicode{tfm:rpzdr/a182}{27AF} \pdfglyphtounicode{tfm:rpzdr/a183}{27B2} \pdfglyphtounicode{tfm:rpzdr/a184}{27B3} \pdfglyphtounicode{tfm:rpzdr/a185}{27B5} \pdfglyphtounicode{tfm:rpzdr/a186}{27B8} \pdfglyphtounicode{tfm:rpzdr/a187}{27BA} \pdfglyphtounicode{tfm:rpzdr/a188}{27BB} \pdfglyphtounicode{tfm:rpzdr/a189}{27BC} \pdfglyphtounicode{tfm:rpzdr/a19}{2713} \pdfglyphtounicode{tfm:rpzdr/a190}{27BD} \pdfglyphtounicode{tfm:rpzdr/a191}{27BE} \pdfglyphtounicode{tfm:rpzdr/a192}{279A} \pdfglyphtounicode{tfm:rpzdr/a193}{27AA} \pdfglyphtounicode{tfm:rpzdr/a194}{27B6} \pdfglyphtounicode{tfm:rpzdr/a195}{27B9} \pdfglyphtounicode{tfm:rpzdr/a196}{2798} \pdfglyphtounicode{tfm:rpzdr/a197}{27B4} \pdfglyphtounicode{tfm:rpzdr/a198}{27B7} \pdfglyphtounicode{tfm:rpzdr/a199}{27AC} \pdfglyphtounicode{tfm:rpzdr/a2}{2702} \pdfglyphtounicode{tfm:rpzdr/a20}{2714} \pdfglyphtounicode{tfm:rpzdr/a200}{27AE} \pdfglyphtounicode{tfm:rpzdr/a201}{27B1} \pdfglyphtounicode{tfm:rpzdr/a202}{2703} \pdfglyphtounicode{tfm:rpzdr/a203}{2750} \pdfglyphtounicode{tfm:rpzdr/a204}{2752} \pdfglyphtounicode{tfm:rpzdr/a205}{276E} \pdfglyphtounicode{tfm:rpzdr/a206}{2770} \pdfglyphtounicode{tfm:rpzdr/a21}{2715} \pdfglyphtounicode{tfm:rpzdr/a22}{2716} \pdfglyphtounicode{tfm:rpzdr/a23}{2717} \pdfglyphtounicode{tfm:rpzdr/a24}{2718} \pdfglyphtounicode{tfm:rpzdr/a25}{2719} \pdfglyphtounicode{tfm:rpzdr/a26}{271A} \pdfglyphtounicode{tfm:rpzdr/a27}{271B} \pdfglyphtounicode{tfm:rpzdr/a28}{271C} \pdfglyphtounicode{tfm:rpzdr/a29}{2722} \pdfglyphtounicode{tfm:rpzdr/a3}{2704} \pdfglyphtounicode{tfm:rpzdr/a30}{2723} \pdfglyphtounicode{tfm:rpzdr/a31}{2724} \pdfglyphtounicode{tfm:rpzdr/a32}{2725} \pdfglyphtounicode{tfm:rpzdr/a33}{2726} \pdfglyphtounicode{tfm:rpzdr/a34}{2727} \pdfglyphtounicode{tfm:rpzdr/a35}{2605} \pdfglyphtounicode{tfm:rpzdr/a36}{2729} \pdfglyphtounicode{tfm:rpzdr/a37}{272A} \pdfglyphtounicode{tfm:rpzdr/a38}{272B} \pdfglyphtounicode{tfm:rpzdr/a39}{272C} \pdfglyphtounicode{tfm:rpzdr/a4}{260E} \pdfglyphtounicode{tfm:rpzdr/a40}{272D} \pdfglyphtounicode{tfm:rpzdr/a41}{272E} \pdfglyphtounicode{tfm:rpzdr/a42}{272F} \pdfglyphtounicode{tfm:rpzdr/a43}{2730} \pdfglyphtounicode{tfm:rpzdr/a44}{2731} \pdfglyphtounicode{tfm:rpzdr/a45}{2732} \pdfglyphtounicode{tfm:rpzdr/a46}{2733} \pdfglyphtounicode{tfm:rpzdr/a47}{2734} \pdfglyphtounicode{tfm:rpzdr/a48}{2735} \pdfglyphtounicode{tfm:rpzdr/a49}{2736} \pdfglyphtounicode{tfm:rpzdr/a5}{2706} \pdfglyphtounicode{tfm:rpzdr/a50}{2737} \pdfglyphtounicode{tfm:rpzdr/a51}{2738} \pdfglyphtounicode{tfm:rpzdr/a52}{2739} \pdfglyphtounicode{tfm:rpzdr/a53}{273A} \pdfglyphtounicode{tfm:rpzdr/a54}{273B} \pdfglyphtounicode{tfm:rpzdr/a55}{273C} \pdfglyphtounicode{tfm:rpzdr/a56}{273D} \pdfglyphtounicode{tfm:rpzdr/a57}{273E} \pdfglyphtounicode{tfm:rpzdr/a58}{273F} \pdfglyphtounicode{tfm:rpzdr/a59}{2740} \pdfglyphtounicode{tfm:rpzdr/a6}{271D} \pdfglyphtounicode{tfm:rpzdr/a60}{2741} \pdfglyphtounicode{tfm:rpzdr/a61}{2742} \pdfglyphtounicode{tfm:rpzdr/a62}{2743} \pdfglyphtounicode{tfm:rpzdr/a63}{2744} \pdfglyphtounicode{tfm:rpzdr/a64}{2745} \pdfglyphtounicode{tfm:rpzdr/a65}{2746} \pdfglyphtounicode{tfm:rpzdr/a66}{2747} \pdfglyphtounicode{tfm:rpzdr/a67}{2748} \pdfglyphtounicode{tfm:rpzdr/a68}{2749} \pdfglyphtounicode{tfm:rpzdr/a69}{274A} \pdfglyphtounicode{tfm:rpzdr/a7}{271E} \pdfglyphtounicode{tfm:rpzdr/a70}{274B} \pdfglyphtounicode{tfm:rpzdr/a71}{25CF} \pdfglyphtounicode{tfm:rpzdr/a72}{274D} \pdfglyphtounicode{tfm:rpzdr/a73}{25A0} \pdfglyphtounicode{tfm:rpzdr/a74}{274F} \pdfglyphtounicode{tfm:rpzdr/a75}{2751} \pdfglyphtounicode{tfm:rpzdr/a76}{25B2} \pdfglyphtounicode{tfm:rpzdr/a77}{25BC} \pdfglyphtounicode{tfm:rpzdr/a78}{25C6} \pdfglyphtounicode{tfm:rpzdr/a79}{2756} \pdfglyphtounicode{tfm:rpzdr/a8}{271F} \pdfglyphtounicode{tfm:rpzdr/a81}{25D7} \pdfglyphtounicode{tfm:rpzdr/a82}{2758} \pdfglyphtounicode{tfm:rpzdr/a83}{2759} \pdfglyphtounicode{tfm:rpzdr/a84}{275A} \pdfglyphtounicode{tfm:rpzdr/a85}{276F} \pdfglyphtounicode{tfm:rpzdr/a86}{2771} \pdfglyphtounicode{tfm:rpzdr/a87}{2772} \pdfglyphtounicode{tfm:rpzdr/a88}{2773} \pdfglyphtounicode{tfm:rpzdr/a89}{2768} \pdfglyphtounicode{tfm:rpzdr/a9}{2720} \pdfglyphtounicode{tfm:rpzdr/a90}{2769} \pdfglyphtounicode{tfm:rpzdr/a91}{276C} \pdfglyphtounicode{tfm:rpzdr/a92}{276D} \pdfglyphtounicode{tfm:rpzdr/a93}{276A} \pdfglyphtounicode{tfm:rpzdr/a94}{276B} \pdfglyphtounicode{tfm:rpzdr/a95}{2774} \pdfglyphtounicode{tfm:rpzdr/a96}{2775} \pdfglyphtounicode{tfm:rpzdr/a97}{275B} \pdfglyphtounicode{tfm:rpzdr/a98}{275C} \pdfglyphtounicode{tfm:rpzdr/a99}{275D} \pdfglyphtounicode{tfm:rtxbmi/phi}{03D5} \pdfglyphtounicode{tfm:rtxbmi/phi1}{03C6} \pdfglyphtounicode{tfm:rtxmi/phi}{03D5} \pdfglyphtounicode{tfm:rtxmi/phi1}{03C6} \pdfglyphtounicode{tfm:txbmia/phi}{03D5} \pdfglyphtounicode{tfm:txbmia/phi1}{03C6} \pdfglyphtounicode{tfm:txbsy/diamond}{2662} \pdfglyphtounicode{tfm:txbsy/heart}{2661} \pdfglyphtounicode{tfm:txbsya/diamond}{2662} \pdfglyphtounicode{tfm:txmia/phi}{03D5} \pdfglyphtounicode{tfm:txmia/phi1}{03C6} \pdfglyphtounicode{tfm:txsy/diamond}{2662} \pdfglyphtounicode{tfm:txsy/heart}{2661} \pdfglyphtounicode{tfm:txsya/diamond}{2662} \pdfglyphtounicode{tfm:zd/a1}{2701} \pdfglyphtounicode{tfm:zd/a10}{2721} \pdfglyphtounicode{tfm:zd/a100}{275E} \pdfglyphtounicode{tfm:zd/a101}{2761} \pdfglyphtounicode{tfm:zd/a102}{2762} \pdfglyphtounicode{tfm:zd/a103}{2763} \pdfglyphtounicode{tfm:zd/a104}{2764} \pdfglyphtounicode{tfm:zd/a105}{2710} \pdfglyphtounicode{tfm:zd/a106}{2765} \pdfglyphtounicode{tfm:zd/a107}{2766} \pdfglyphtounicode{tfm:zd/a108}{2767} \pdfglyphtounicode{tfm:zd/a109}{2660} \pdfglyphtounicode{tfm:zd/a11}{261B} \pdfglyphtounicode{tfm:zd/a110}{2665} \pdfglyphtounicode{tfm:zd/a111}{2666} \pdfglyphtounicode{tfm:zd/a112}{2663} \pdfglyphtounicode{tfm:zd/a117}{2709} \pdfglyphtounicode{tfm:zd/a118}{2708} \pdfglyphtounicode{tfm:zd/a119}{2707} \pdfglyphtounicode{tfm:zd/a12}{261E} \pdfglyphtounicode{tfm:zd/a120}{2460} \pdfglyphtounicode{tfm:zd/a121}{2461} \pdfglyphtounicode{tfm:zd/a122}{2462} \pdfglyphtounicode{tfm:zd/a123}{2463} \pdfglyphtounicode{tfm:zd/a124}{2464} \pdfglyphtounicode{tfm:zd/a125}{2465} \pdfglyphtounicode{tfm:zd/a126}{2466} \pdfglyphtounicode{tfm:zd/a127}{2467} \pdfglyphtounicode{tfm:zd/a128}{2468} \pdfglyphtounicode{tfm:zd/a129}{2469} \pdfglyphtounicode{tfm:zd/a13}{270C} \pdfglyphtounicode{tfm:zd/a130}{2776} \pdfglyphtounicode{tfm:zd/a131}{2777} \pdfglyphtounicode{tfm:zd/a132}{2778} \pdfglyphtounicode{tfm:zd/a133}{2779} \pdfglyphtounicode{tfm:zd/a134}{277A} \pdfglyphtounicode{tfm:zd/a135}{277B} \pdfglyphtounicode{tfm:zd/a136}{277C} \pdfglyphtounicode{tfm:zd/a137}{277D} \pdfglyphtounicode{tfm:zd/a138}{277E} \pdfglyphtounicode{tfm:zd/a139}{277F} \pdfglyphtounicode{tfm:zd/a14}{270D} \pdfglyphtounicode{tfm:zd/a140}{2780} \pdfglyphtounicode{tfm:zd/a141}{2781} \pdfglyphtounicode{tfm:zd/a142}{2782} \pdfglyphtounicode{tfm:zd/a143}{2783} \pdfglyphtounicode{tfm:zd/a144}{2784} \pdfglyphtounicode{tfm:zd/a145}{2785} \pdfglyphtounicode{tfm:zd/a146}{2786} \pdfglyphtounicode{tfm:zd/a147}{2787} \pdfglyphtounicode{tfm:zd/a148}{2788} \pdfglyphtounicode{tfm:zd/a149}{2789} \pdfglyphtounicode{tfm:zd/a15}{270E} \pdfglyphtounicode{tfm:zd/a150}{278A} \pdfglyphtounicode{tfm:zd/a151}{278B} \pdfglyphtounicode{tfm:zd/a152}{278C} \pdfglyphtounicode{tfm:zd/a153}{278D} \pdfglyphtounicode{tfm:zd/a154}{278E} \pdfglyphtounicode{tfm:zd/a155}{278F} \pdfglyphtounicode{tfm:zd/a156}{2790} \pdfglyphtounicode{tfm:zd/a157}{2791} \pdfglyphtounicode{tfm:zd/a158}{2792} \pdfglyphtounicode{tfm:zd/a159}{2793} \pdfglyphtounicode{tfm:zd/a16}{270F} \pdfglyphtounicode{tfm:zd/a160}{2794} \pdfglyphtounicode{tfm:zd/a161}{2192} \pdfglyphtounicode{tfm:zd/a162}{27A3} \pdfglyphtounicode{tfm:zd/a163}{2194} \pdfglyphtounicode{tfm:zd/a164}{2195} \pdfglyphtounicode{tfm:zd/a165}{2799} \pdfglyphtounicode{tfm:zd/a166}{279B} \pdfglyphtounicode{tfm:zd/a167}{279C} \pdfglyphtounicode{tfm:zd/a168}{279D} \pdfglyphtounicode{tfm:zd/a169}{279E} \pdfglyphtounicode{tfm:zd/a17}{2711} \pdfglyphtounicode{tfm:zd/a170}{279F} \pdfglyphtounicode{tfm:zd/a171}{27A0} \pdfglyphtounicode{tfm:zd/a172}{27A1} \pdfglyphtounicode{tfm:zd/a173}{27A2} \pdfglyphtounicode{tfm:zd/a174}{27A4} \pdfglyphtounicode{tfm:zd/a175}{27A5} \pdfglyphtounicode{tfm:zd/a176}{27A6} \pdfglyphtounicode{tfm:zd/a177}{27A7} \pdfglyphtounicode{tfm:zd/a178}{27A8} \pdfglyphtounicode{tfm:zd/a179}{27A9} \pdfglyphtounicode{tfm:zd/a18}{2712} \pdfglyphtounicode{tfm:zd/a180}{27AB} \pdfglyphtounicode{tfm:zd/a181}{27AD} \pdfglyphtounicode{tfm:zd/a182}{27AF} \pdfglyphtounicode{tfm:zd/a183}{27B2} \pdfglyphtounicode{tfm:zd/a184}{27B3} \pdfglyphtounicode{tfm:zd/a185}{27B5} \pdfglyphtounicode{tfm:zd/a186}{27B8} \pdfglyphtounicode{tfm:zd/a187}{27BA} \pdfglyphtounicode{tfm:zd/a188}{27BB} \pdfglyphtounicode{tfm:zd/a189}{27BC} \pdfglyphtounicode{tfm:zd/a19}{2713} \pdfglyphtounicode{tfm:zd/a190}{27BD} \pdfglyphtounicode{tfm:zd/a191}{27BE} \pdfglyphtounicode{tfm:zd/a192}{279A} \pdfglyphtounicode{tfm:zd/a193}{27AA} \pdfglyphtounicode{tfm:zd/a194}{27B6} \pdfglyphtounicode{tfm:zd/a195}{27B9} \pdfglyphtounicode{tfm:zd/a196}{2798} \pdfglyphtounicode{tfm:zd/a197}{27B4} \pdfglyphtounicode{tfm:zd/a198}{27B7} \pdfglyphtounicode{tfm:zd/a199}{27AC} \pdfglyphtounicode{tfm:zd/a2}{2702} \pdfglyphtounicode{tfm:zd/a20}{2714} \pdfglyphtounicode{tfm:zd/a200}{27AE} \pdfglyphtounicode{tfm:zd/a201}{27B1} \pdfglyphtounicode{tfm:zd/a202}{2703} \pdfglyphtounicode{tfm:zd/a203}{2750} \pdfglyphtounicode{tfm:zd/a204}{2752} \pdfglyphtounicode{tfm:zd/a205}{276E} \pdfglyphtounicode{tfm:zd/a206}{2770} \pdfglyphtounicode{tfm:zd/a21}{2715} \pdfglyphtounicode{tfm:zd/a22}{2716} \pdfglyphtounicode{tfm:zd/a23}{2717} \pdfglyphtounicode{tfm:zd/a24}{2718} \pdfglyphtounicode{tfm:zd/a25}{2719} \pdfglyphtounicode{tfm:zd/a26}{271A} \pdfglyphtounicode{tfm:zd/a27}{271B} \pdfglyphtounicode{tfm:zd/a28}{271C} \pdfglyphtounicode{tfm:zd/a29}{2722} \pdfglyphtounicode{tfm:zd/a3}{2704} \pdfglyphtounicode{tfm:zd/a30}{2723} \pdfglyphtounicode{tfm:zd/a31}{2724} \pdfglyphtounicode{tfm:zd/a32}{2725} \pdfglyphtounicode{tfm:zd/a33}{2726} \pdfglyphtounicode{tfm:zd/a34}{2727} \pdfglyphtounicode{tfm:zd/a35}{2605} \pdfglyphtounicode{tfm:zd/a36}{2729} \pdfglyphtounicode{tfm:zd/a37}{272A} \pdfglyphtounicode{tfm:zd/a38}{272B} \pdfglyphtounicode{tfm:zd/a39}{272C} \pdfglyphtounicode{tfm:zd/a4}{260E} \pdfglyphtounicode{tfm:zd/a40}{272D} \pdfglyphtounicode{tfm:zd/a41}{272E} \pdfglyphtounicode{tfm:zd/a42}{272F} \pdfglyphtounicode{tfm:zd/a43}{2730} \pdfglyphtounicode{tfm:zd/a44}{2731} \pdfglyphtounicode{tfm:zd/a45}{2732} \pdfglyphtounicode{tfm:zd/a46}{2733} \pdfglyphtounicode{tfm:zd/a47}{2734} \pdfglyphtounicode{tfm:zd/a48}{2735} \pdfglyphtounicode{tfm:zd/a49}{2736} \pdfglyphtounicode{tfm:zd/a5}{2706} \pdfglyphtounicode{tfm:zd/a50}{2737} \pdfglyphtounicode{tfm:zd/a51}{2738} \pdfglyphtounicode{tfm:zd/a52}{2739} \pdfglyphtounicode{tfm:zd/a53}{273A} \pdfglyphtounicode{tfm:zd/a54}{273B} \pdfglyphtounicode{tfm:zd/a55}{273C} \pdfglyphtounicode{tfm:zd/a56}{273D} \pdfglyphtounicode{tfm:zd/a57}{273E} \pdfglyphtounicode{tfm:zd/a58}{273F} \pdfglyphtounicode{tfm:zd/a59}{2740} \pdfglyphtounicode{tfm:zd/a6}{271D} \pdfglyphtounicode{tfm:zd/a60}{2741} \pdfglyphtounicode{tfm:zd/a61}{2742} \pdfglyphtounicode{tfm:zd/a62}{2743} \pdfglyphtounicode{tfm:zd/a63}{2744} \pdfglyphtounicode{tfm:zd/a64}{2745} \pdfglyphtounicode{tfm:zd/a65}{2746} \pdfglyphtounicode{tfm:zd/a66}{2747} \pdfglyphtounicode{tfm:zd/a67}{2748} \pdfglyphtounicode{tfm:zd/a68}{2749} \pdfglyphtounicode{tfm:zd/a69}{274A} \pdfglyphtounicode{tfm:zd/a7}{271E} \pdfglyphtounicode{tfm:zd/a70}{274B} \pdfglyphtounicode{tfm:zd/a71}{25CF} \pdfglyphtounicode{tfm:zd/a72}{274D} \pdfglyphtounicode{tfm:zd/a73}{25A0} \pdfglyphtounicode{tfm:zd/a74}{274F} \pdfglyphtounicode{tfm:zd/a75}{2751} \pdfglyphtounicode{tfm:zd/a76}{25B2} \pdfglyphtounicode{tfm:zd/a77}{25BC} \pdfglyphtounicode{tfm:zd/a78}{25C6} \pdfglyphtounicode{tfm:zd/a79}{2756} \pdfglyphtounicode{tfm:zd/a8}{271F} \pdfglyphtounicode{tfm:zd/a81}{25D7} \pdfglyphtounicode{tfm:zd/a82}{2758} \pdfglyphtounicode{tfm:zd/a83}{2759} \pdfglyphtounicode{tfm:zd/a84}{275A} \pdfglyphtounicode{tfm:zd/a85}{276F} \pdfglyphtounicode{tfm:zd/a86}{2771} \pdfglyphtounicode{tfm:zd/a87}{2772} \pdfglyphtounicode{tfm:zd/a88}{2773} \pdfglyphtounicode{tfm:zd/a89}{2768} \pdfglyphtounicode{tfm:zd/a9}{2720} \pdfglyphtounicode{tfm:zd/a90}{2769} \pdfglyphtounicode{tfm:zd/a91}{276C} \pdfglyphtounicode{tfm:zd/a92}{276D} \pdfglyphtounicode{tfm:zd/a93}{276A} \pdfglyphtounicode{tfm:zd/a94}{276B} \pdfglyphtounicode{tfm:zd/a95}{2774} \pdfglyphtounicode{tfm:zd/a96}{2775} \pdfglyphtounicode{tfm:zd/a97}{275B} \pdfglyphtounicode{tfm:zd/a98}{275C} \pdfglyphtounicode{tfm:zd/a99}{275D} \pdfglyphtounicode{tfm:zpzdr-reversed/a1}{2701} \pdfglyphtounicode{tfm:zpzdr-reversed/a10}{2721} \pdfglyphtounicode{tfm:zpzdr-reversed/a100}{275E} \pdfglyphtounicode{tfm:zpzdr-reversed/a101}{2761} \pdfglyphtounicode{tfm:zpzdr-reversed/a102}{2762} \pdfglyphtounicode{tfm:zpzdr-reversed/a103}{2763} \pdfglyphtounicode{tfm:zpzdr-reversed/a104}{2764} \pdfglyphtounicode{tfm:zpzdr-reversed/a105}{2710} \pdfglyphtounicode{tfm:zpzdr-reversed/a106}{2765} \pdfglyphtounicode{tfm:zpzdr-reversed/a107}{2766} \pdfglyphtounicode{tfm:zpzdr-reversed/a108}{2767} \pdfglyphtounicode{tfm:zpzdr-reversed/a109}{2660} \pdfglyphtounicode{tfm:zpzdr-reversed/a11}{261B} \pdfglyphtounicode{tfm:zpzdr-reversed/a110}{2665} \pdfglyphtounicode{tfm:zpzdr-reversed/a111}{2666} \pdfglyphtounicode{tfm:zpzdr-reversed/a112}{2663} \pdfglyphtounicode{tfm:zpzdr-reversed/a117}{2709} \pdfglyphtounicode{tfm:zpzdr-reversed/a118}{2708} \pdfglyphtounicode{tfm:zpzdr-reversed/a119}{2707} \pdfglyphtounicode{tfm:zpzdr-reversed/a12}{261E} \pdfglyphtounicode{tfm:zpzdr-reversed/a120}{2460} \pdfglyphtounicode{tfm:zpzdr-reversed/a121}{2461} \pdfglyphtounicode{tfm:zpzdr-reversed/a122}{2462} \pdfglyphtounicode{tfm:zpzdr-reversed/a123}{2463} \pdfglyphtounicode{tfm:zpzdr-reversed/a124}{2464} \pdfglyphtounicode{tfm:zpzdr-reversed/a125}{2465} \pdfglyphtounicode{tfm:zpzdr-reversed/a126}{2466} \pdfglyphtounicode{tfm:zpzdr-reversed/a127}{2467} \pdfglyphtounicode{tfm:zpzdr-reversed/a128}{2468} \pdfglyphtounicode{tfm:zpzdr-reversed/a129}{2469} \pdfglyphtounicode{tfm:zpzdr-reversed/a13}{270C} \pdfglyphtounicode{tfm:zpzdr-reversed/a130}{2776} \pdfglyphtounicode{tfm:zpzdr-reversed/a131}{2777} \pdfglyphtounicode{tfm:zpzdr-reversed/a132}{2778} \pdfglyphtounicode{tfm:zpzdr-reversed/a133}{2779} \pdfglyphtounicode{tfm:zpzdr-reversed/a134}{277A} \pdfglyphtounicode{tfm:zpzdr-reversed/a135}{277B} \pdfglyphtounicode{tfm:zpzdr-reversed/a136}{277C} \pdfglyphtounicode{tfm:zpzdr-reversed/a137}{277D} \pdfglyphtounicode{tfm:zpzdr-reversed/a138}{277E} \pdfglyphtounicode{tfm:zpzdr-reversed/a139}{277F} \pdfglyphtounicode{tfm:zpzdr-reversed/a14}{270D} \pdfglyphtounicode{tfm:zpzdr-reversed/a140}{2780} \pdfglyphtounicode{tfm:zpzdr-reversed/a141}{2781} \pdfglyphtounicode{tfm:zpzdr-reversed/a142}{2782} \pdfglyphtounicode{tfm:zpzdr-reversed/a143}{2783} \pdfglyphtounicode{tfm:zpzdr-reversed/a144}{2784} \pdfglyphtounicode{tfm:zpzdr-reversed/a145}{2785} \pdfglyphtounicode{tfm:zpzdr-reversed/a146}{2786} \pdfglyphtounicode{tfm:zpzdr-reversed/a147}{2787} \pdfglyphtounicode{tfm:zpzdr-reversed/a148}{2788} \pdfglyphtounicode{tfm:zpzdr-reversed/a149}{2789} \pdfglyphtounicode{tfm:zpzdr-reversed/a15}{270E} \pdfglyphtounicode{tfm:zpzdr-reversed/a150}{278A} \pdfglyphtounicode{tfm:zpzdr-reversed/a151}{278B} \pdfglyphtounicode{tfm:zpzdr-reversed/a152}{278C} \pdfglyphtounicode{tfm:zpzdr-reversed/a153}{278D} \pdfglyphtounicode{tfm:zpzdr-reversed/a154}{278E} \pdfglyphtounicode{tfm:zpzdr-reversed/a155}{278F} \pdfglyphtounicode{tfm:zpzdr-reversed/a156}{2790} \pdfglyphtounicode{tfm:zpzdr-reversed/a157}{2791} \pdfglyphtounicode{tfm:zpzdr-reversed/a158}{2792} \pdfglyphtounicode{tfm:zpzdr-reversed/a159}{2793} \pdfglyphtounicode{tfm:zpzdr-reversed/a16}{270F} \pdfglyphtounicode{tfm:zpzdr-reversed/a160}{2794} \pdfglyphtounicode{tfm:zpzdr-reversed/a161}{2192} \pdfglyphtounicode{tfm:zpzdr-reversed/a162}{27A3} \pdfglyphtounicode{tfm:zpzdr-reversed/a163}{2194} \pdfglyphtounicode{tfm:zpzdr-reversed/a164}{2195} \pdfglyphtounicode{tfm:zpzdr-reversed/a165}{2799} \pdfglyphtounicode{tfm:zpzdr-reversed/a166}{279B} \pdfglyphtounicode{tfm:zpzdr-reversed/a167}{279C} \pdfglyphtounicode{tfm:zpzdr-reversed/a168}{279D} \pdfglyphtounicode{tfm:zpzdr-reversed/a169}{279E} \pdfglyphtounicode{tfm:zpzdr-reversed/a17}{2711} \pdfglyphtounicode{tfm:zpzdr-reversed/a170}{279F} \pdfglyphtounicode{tfm:zpzdr-reversed/a171}{27A0} \pdfglyphtounicode{tfm:zpzdr-reversed/a172}{27A1} \pdfglyphtounicode{tfm:zpzdr-reversed/a173}{27A2} \pdfglyphtounicode{tfm:zpzdr-reversed/a174}{27A4} \pdfglyphtounicode{tfm:zpzdr-reversed/a175}{27A5} \pdfglyphtounicode{tfm:zpzdr-reversed/a176}{27A6} \pdfglyphtounicode{tfm:zpzdr-reversed/a177}{27A7} \pdfglyphtounicode{tfm:zpzdr-reversed/a178}{27A8} \pdfglyphtounicode{tfm:zpzdr-reversed/a179}{27A9} \pdfglyphtounicode{tfm:zpzdr-reversed/a18}{2712} \pdfglyphtounicode{tfm:zpzdr-reversed/a180}{27AB} \pdfglyphtounicode{tfm:zpzdr-reversed/a181}{27AD} \pdfglyphtounicode{tfm:zpzdr-reversed/a182}{27AF} \pdfglyphtounicode{tfm:zpzdr-reversed/a183}{27B2} \pdfglyphtounicode{tfm:zpzdr-reversed/a184}{27B3} \pdfglyphtounicode{tfm:zpzdr-reversed/a185}{27B5} \pdfglyphtounicode{tfm:zpzdr-reversed/a186}{27B8} \pdfglyphtounicode{tfm:zpzdr-reversed/a187}{27BA} \pdfglyphtounicode{tfm:zpzdr-reversed/a188}{27BB} \pdfglyphtounicode{tfm:zpzdr-reversed/a189}{27BC} \pdfglyphtounicode{tfm:zpzdr-reversed/a19}{2713} \pdfglyphtounicode{tfm:zpzdr-reversed/a190}{27BD} \pdfglyphtounicode{tfm:zpzdr-reversed/a191}{27BE} \pdfglyphtounicode{tfm:zpzdr-reversed/a192}{279A} \pdfglyphtounicode{tfm:zpzdr-reversed/a193}{27AA} \pdfglyphtounicode{tfm:zpzdr-reversed/a194}{27B6} \pdfglyphtounicode{tfm:zpzdr-reversed/a195}{27B9} \pdfglyphtounicode{tfm:zpzdr-reversed/a196}{2798} \pdfglyphtounicode{tfm:zpzdr-reversed/a197}{27B4} \pdfglyphtounicode{tfm:zpzdr-reversed/a198}{27B7} \pdfglyphtounicode{tfm:zpzdr-reversed/a199}{27AC} \pdfglyphtounicode{tfm:zpzdr-reversed/a2}{2702} \pdfglyphtounicode{tfm:zpzdr-reversed/a20}{2714} \pdfglyphtounicode{tfm:zpzdr-reversed/a200}{27AE} \pdfglyphtounicode{tfm:zpzdr-reversed/a201}{27B1} \pdfglyphtounicode{tfm:zpzdr-reversed/a202}{2703} \pdfglyphtounicode{tfm:zpzdr-reversed/a203}{2750} \pdfglyphtounicode{tfm:zpzdr-reversed/a204}{2752} \pdfglyphtounicode{tfm:zpzdr-reversed/a205}{276E} \pdfglyphtounicode{tfm:zpzdr-reversed/a206}{2770} \pdfglyphtounicode{tfm:zpzdr-reversed/a21}{2715} \pdfglyphtounicode{tfm:zpzdr-reversed/a22}{2716} \pdfglyphtounicode{tfm:zpzdr-reversed/a23}{2717} \pdfglyphtounicode{tfm:zpzdr-reversed/a24}{2718} \pdfglyphtounicode{tfm:zpzdr-reversed/a25}{2719} \pdfglyphtounicode{tfm:zpzdr-reversed/a26}{271A} \pdfglyphtounicode{tfm:zpzdr-reversed/a27}{271B} \pdfglyphtounicode{tfm:zpzdr-reversed/a28}{271C} \pdfglyphtounicode{tfm:zpzdr-reversed/a29}{2722} \pdfglyphtounicode{tfm:zpzdr-reversed/a3}{2704} \pdfglyphtounicode{tfm:zpzdr-reversed/a30}{2723} \pdfglyphtounicode{tfm:zpzdr-reversed/a31}{2724} \pdfglyphtounicode{tfm:zpzdr-reversed/a32}{2725} \pdfglyphtounicode{tfm:zpzdr-reversed/a33}{2726} \pdfglyphtounicode{tfm:zpzdr-reversed/a34}{2727} \pdfglyphtounicode{tfm:zpzdr-reversed/a35}{2605} \pdfglyphtounicode{tfm:zpzdr-reversed/a36}{2729} \pdfglyphtounicode{tfm:zpzdr-reversed/a37}{272A} \pdfglyphtounicode{tfm:zpzdr-reversed/a38}{272B} \pdfglyphtounicode{tfm:zpzdr-reversed/a39}{272C} \pdfglyphtounicode{tfm:zpzdr-reversed/a4}{260E} \pdfglyphtounicode{tfm:zpzdr-reversed/a40}{272D} \pdfglyphtounicode{tfm:zpzdr-reversed/a41}{272E} \pdfglyphtounicode{tfm:zpzdr-reversed/a42}{272F} \pdfglyphtounicode{tfm:zpzdr-reversed/a43}{2730} \pdfglyphtounicode{tfm:zpzdr-reversed/a44}{2731} \pdfglyphtounicode{tfm:zpzdr-reversed/a45}{2732} \pdfglyphtounicode{tfm:zpzdr-reversed/a46}{2733} \pdfglyphtounicode{tfm:zpzdr-reversed/a47}{2734} \pdfglyphtounicode{tfm:zpzdr-reversed/a48}{2735} \pdfglyphtounicode{tfm:zpzdr-reversed/a49}{2736} \pdfglyphtounicode{tfm:zpzdr-reversed/a5}{2706} \pdfglyphtounicode{tfm:zpzdr-reversed/a50}{2737} \pdfglyphtounicode{tfm:zpzdr-reversed/a51}{2738} \pdfglyphtounicode{tfm:zpzdr-reversed/a52}{2739} \pdfglyphtounicode{tfm:zpzdr-reversed/a53}{273A} \pdfglyphtounicode{tfm:zpzdr-reversed/a54}{273B} \pdfglyphtounicode{tfm:zpzdr-reversed/a55}{273C} \pdfglyphtounicode{tfm:zpzdr-reversed/a56}{273D} \pdfglyphtounicode{tfm:zpzdr-reversed/a57}{273E} \pdfglyphtounicode{tfm:zpzdr-reversed/a58}{273F} \pdfglyphtounicode{tfm:zpzdr-reversed/a59}{2740} \pdfglyphtounicode{tfm:zpzdr-reversed/a6}{271D} \pdfglyphtounicode{tfm:zpzdr-reversed/a60}{2741} \pdfglyphtounicode{tfm:zpzdr-reversed/a61}{2742} \pdfglyphtounicode{tfm:zpzdr-reversed/a62}{2743} \pdfglyphtounicode{tfm:zpzdr-reversed/a63}{2744} \pdfglyphtounicode{tfm:zpzdr-reversed/a64}{2745} \pdfglyphtounicode{tfm:zpzdr-reversed/a65}{2746} \pdfglyphtounicode{tfm:zpzdr-reversed/a66}{2747} \pdfglyphtounicode{tfm:zpzdr-reversed/a67}{2748} \pdfglyphtounicode{tfm:zpzdr-reversed/a68}{2749} \pdfglyphtounicode{tfm:zpzdr-reversed/a69}{274A} \pdfglyphtounicode{tfm:zpzdr-reversed/a7}{271E} \pdfglyphtounicode{tfm:zpzdr-reversed/a70}{274B} \pdfglyphtounicode{tfm:zpzdr-reversed/a71}{25CF} \pdfglyphtounicode{tfm:zpzdr-reversed/a72}{274D} \pdfglyphtounicode{tfm:zpzdr-reversed/a73}{25A0} \pdfglyphtounicode{tfm:zpzdr-reversed/a74}{274F} \pdfglyphtounicode{tfm:zpzdr-reversed/a75}{2751} \pdfglyphtounicode{tfm:zpzdr-reversed/a76}{25B2} \pdfglyphtounicode{tfm:zpzdr-reversed/a77}{25BC} \pdfglyphtounicode{tfm:zpzdr-reversed/a78}{25C6} \pdfglyphtounicode{tfm:zpzdr-reversed/a79}{2756} \pdfglyphtounicode{tfm:zpzdr-reversed/a8}{271F} \pdfglyphtounicode{tfm:zpzdr-reversed/a81}{25D7} \pdfglyphtounicode{tfm:zpzdr-reversed/a82}{2758} \pdfglyphtounicode{tfm:zpzdr-reversed/a83}{2759} \pdfglyphtounicode{tfm:zpzdr-reversed/a84}{275A} \pdfglyphtounicode{tfm:zpzdr-reversed/a85}{276F} \pdfglyphtounicode{tfm:zpzdr-reversed/a86}{2771} \pdfglyphtounicode{tfm:zpzdr-reversed/a87}{2772} \pdfglyphtounicode{tfm:zpzdr-reversed/a88}{2773} \pdfglyphtounicode{tfm:zpzdr-reversed/a89}{2768} \pdfglyphtounicode{tfm:zpzdr-reversed/a9}{2720} \pdfglyphtounicode{tfm:zpzdr-reversed/a90}{2769} \pdfglyphtounicode{tfm:zpzdr-reversed/a91}{276C} \pdfglyphtounicode{tfm:zpzdr-reversed/a92}{276D} \pdfglyphtounicode{tfm:zpzdr-reversed/a93}{276A} \pdfglyphtounicode{tfm:zpzdr-reversed/a94}{276B} \pdfglyphtounicode{tfm:zpzdr-reversed/a95}{2774} \pdfglyphtounicode{tfm:zpzdr-reversed/a96}{2775} \pdfglyphtounicode{tfm:zpzdr-reversed/a97}{275B} \pdfglyphtounicode{tfm:zpzdr-reversed/a98}{275C} \pdfglyphtounicode{tfm:zpzdr-reversed/a99}{275D} \pdfglyphtounicode{thabengali}{09A5} \pdfglyphtounicode{thadeva}{0925} \pdfglyphtounicode{thagujarati}{0AA5} \pdfglyphtounicode{thagurmukhi}{0A25} \pdfglyphtounicode{thalarabic}{0630} \pdfglyphtounicode{thalfinalarabic}{FEAC} \pdfglyphtounicode{thanthakhatlowleftthai}{F898} \pdfglyphtounicode{thanthakhatlowrightthai}{F897} \pdfglyphtounicode{thanthakhatthai}{0E4C} \pdfglyphtounicode{thanthakhatupperleftthai}{F896} \pdfglyphtounicode{theharabic}{062B} \pdfglyphtounicode{thehfinalarabic}{FE9A} \pdfglyphtounicode{thehinitialarabic}{FE9B} \pdfglyphtounicode{thehmedialarabic}{FE9C} \pdfglyphtounicode{thereexists}{2203} \pdfglyphtounicode{therefore}{2234} \pdfglyphtounicode{theta}{03B8} \pdfglyphtounicode{theta1}{03D1} \pdfglyphtounicode{thetasymbolgreek}{03D1} \pdfglyphtounicode{thieuthacirclekorean}{3279} \pdfglyphtounicode{thieuthaparenkorean}{3219} \pdfglyphtounicode{thieuthcirclekorean}{326B} \pdfglyphtounicode{thieuthkorean}{314C} \pdfglyphtounicode{thieuthparenkorean}{320B} \pdfglyphtounicode{thirteencircle}{246C} \pdfglyphtounicode{thirteenparen}{2480} \pdfglyphtounicode{thirteenperiod}{2494} \pdfglyphtounicode{thonangmonthothai}{0E11} \pdfglyphtounicode{thook}{01AD} \pdfglyphtounicode{thophuthaothai}{0E12} \pdfglyphtounicode{thorn}{00FE} \pdfglyphtounicode{thothahanthai}{0E17} \pdfglyphtounicode{thothanthai}{0E10} \pdfglyphtounicode{thothongthai}{0E18} \pdfglyphtounicode{thothungthai}{0E16} \pdfglyphtounicode{thousandcyrillic}{0482} \pdfglyphtounicode{thousandsseparatorarabic}{066C} \pdfglyphtounicode{thousandsseparatorpersian}{066C} \pdfglyphtounicode{three}{0033} \pdfglyphtounicode{threearabic}{0663} \pdfglyphtounicode{threebengali}{09E9} \pdfglyphtounicode{threecircle}{2462} \pdfglyphtounicode{threecircleinversesansserif}{278C} \pdfglyphtounicode{threedeva}{0969} \pdfglyphtounicode{threeeighths}{215C} \pdfglyphtounicode{threegujarati}{0AE9} \pdfglyphtounicode{threegurmukhi}{0A69} \pdfglyphtounicode{threehackarabic}{0663} \pdfglyphtounicode{threehangzhou}{3023} \pdfglyphtounicode{threeideographicparen}{3222} \pdfglyphtounicode{threeinferior}{2083} \pdfglyphtounicode{threemonospace}{FF13} \pdfglyphtounicode{threenumeratorbengali}{09F6} \pdfglyphtounicode{threeoldstyle}{0033} \pdfglyphtounicode{threeparen}{2476} \pdfglyphtounicode{threeperiod}{248A} \pdfglyphtounicode{threepersian}{06F3} \pdfglyphtounicode{threequarters}{00BE} \pdfglyphtounicode{threequartersemdash}{F6DE} \pdfglyphtounicode{threeroman}{2172} \pdfglyphtounicode{threesuperior}{00B3} \pdfglyphtounicode{threethai}{0E53} \pdfglyphtounicode{thzsquare}{3394} \pdfglyphtounicode{tihiragana}{3061} \pdfglyphtounicode{tikatakana}{30C1} \pdfglyphtounicode{tikatakanahalfwidth}{FF81} \pdfglyphtounicode{tikeutacirclekorean}{3270} \pdfglyphtounicode{tikeutaparenkorean}{3210} \pdfglyphtounicode{tikeutcirclekorean}{3262} \pdfglyphtounicode{tikeutkorean}{3137} \pdfglyphtounicode{tikeutparenkorean}{3202} \pdfglyphtounicode{tilde}{02DC} \pdfglyphtounicode{tildebelowcmb}{0330} \pdfglyphtounicode{tildecmb}{0303} \pdfglyphtounicode{tildecomb}{0303} \pdfglyphtounicode{tildedoublecmb}{0360} \pdfglyphtounicode{tildeoperator}{223C} \pdfglyphtounicode{tildeoverlaycmb}{0334} \pdfglyphtounicode{tildeverticalcmb}{033E} \pdfglyphtounicode{timescircle}{2297} \pdfglyphtounicode{tipehahebrew}{0596} \pdfglyphtounicode{tipehalefthebrew}{0596} \pdfglyphtounicode{tippigurmukhi}{0A70} \pdfglyphtounicode{titlocyrilliccmb}{0483} \pdfglyphtounicode{tiwnarmenian}{057F} \pdfglyphtounicode{tlinebelow}{1E6F} \pdfglyphtounicode{tmonospace}{FF54} \pdfglyphtounicode{toarmenian}{0569} \pdfglyphtounicode{tohiragana}{3068} \pdfglyphtounicode{tokatakana}{30C8} \pdfglyphtounicode{tokatakanahalfwidth}{FF84} \pdfglyphtounicode{tonebarextrahighmod}{02E5} \pdfglyphtounicode{tonebarextralowmod}{02E9} \pdfglyphtounicode{tonebarhighmod}{02E6} \pdfglyphtounicode{tonebarlowmod}{02E8} \pdfglyphtounicode{tonebarmidmod}{02E7} \pdfglyphtounicode{tonefive}{01BD} \pdfglyphtounicode{tonesix}{0185} \pdfglyphtounicode{tonetwo}{01A8} \pdfglyphtounicode{tonos}{0384} \pdfglyphtounicode{tonsquare}{3327} \pdfglyphtounicode{topatakthai}{0E0F} \pdfglyphtounicode{tortoiseshellbracketleft}{3014} \pdfglyphtounicode{tortoiseshellbracketleftsmall}{FE5D} \pdfglyphtounicode{tortoiseshellbracketleftvertical}{FE39} \pdfglyphtounicode{tortoiseshellbracketright}{3015} \pdfglyphtounicode{tortoiseshellbracketrightsmall}{FE5E} \pdfglyphtounicode{tortoiseshellbracketrightvertical}{FE3A} \pdfglyphtounicode{totaothai}{0E15} \pdfglyphtounicode{tpalatalhook}{01AB} \pdfglyphtounicode{tparen}{24AF} \pdfglyphtounicode{trademark}{2122} \pdfglyphtounicode{trademarksans}{2122} \pdfglyphtounicode{trademarkserif}{2122} \pdfglyphtounicode{tretroflexhook}{0288} \pdfglyphtounicode{triagdn}{25BC} \pdfglyphtounicode{triaglf}{25C4} \pdfglyphtounicode{triagrt}{25BA} \pdfglyphtounicode{triagup}{25B2} \pdfglyphtounicode{triangle}{25B3} \pdfglyphtounicode{triangledownsld}{25BC} \pdfglyphtounicode{triangleinv}{25BD} \pdfglyphtounicode{triangleleft}{25C1} \pdfglyphtounicode{triangleleftequal}{22B4} \pdfglyphtounicode{triangleleftsld}{25C0} \pdfglyphtounicode{triangleright}{25B7} \pdfglyphtounicode{trianglerightequal}{22B5} \pdfglyphtounicode{trianglerightsld}{25B6} \pdfglyphtounicode{trianglesolid}{25B2} \pdfglyphtounicode{ts}{02A6} \pdfglyphtounicode{tsadi}{05E6} \pdfglyphtounicode{tsadidagesh}{FB46} \pdfglyphtounicode{tsadidageshhebrew}{FB46} \pdfglyphtounicode{tsadihebrew}{05E6} \pdfglyphtounicode{tsecyrillic}{0446} \pdfglyphtounicode{tsere}{05B5} \pdfglyphtounicode{tsere12}{05B5} \pdfglyphtounicode{tsere1e}{05B5} \pdfglyphtounicode{tsere2b}{05B5} \pdfglyphtounicode{tserehebrew}{05B5} \pdfglyphtounicode{tserenarrowhebrew}{05B5} \pdfglyphtounicode{tserequarterhebrew}{05B5} \pdfglyphtounicode{tserewidehebrew}{05B5} \pdfglyphtounicode{tshecyrillic}{045B} \pdfglyphtounicode{tsuperior}{0074} \pdfglyphtounicode{ttabengali}{099F} \pdfglyphtounicode{ttadeva}{091F} \pdfglyphtounicode{ttagujarati}{0A9F} \pdfglyphtounicode{ttagurmukhi}{0A1F} \pdfglyphtounicode{tteharabic}{0679} \pdfglyphtounicode{ttehfinalarabic}{FB67} \pdfglyphtounicode{ttehinitialarabic}{FB68} \pdfglyphtounicode{ttehmedialarabic}{FB69} \pdfglyphtounicode{tthabengali}{09A0} \pdfglyphtounicode{tthadeva}{0920} \pdfglyphtounicode{tthagujarati}{0AA0} \pdfglyphtounicode{tthagurmukhi}{0A20} \pdfglyphtounicode{tturned}{0287} \pdfglyphtounicode{tuhiragana}{3064} \pdfglyphtounicode{tukatakana}{30C4} \pdfglyphtounicode{tukatakanahalfwidth}{FF82} \pdfglyphtounicode{turnstileleft}{22A2} \pdfglyphtounicode{turnstileright}{22A3} \pdfglyphtounicode{tusmallhiragana}{3063} \pdfglyphtounicode{tusmallkatakana}{30C3} \pdfglyphtounicode{tusmallkatakanahalfwidth}{FF6F} \pdfglyphtounicode{twelvecircle}{246B} \pdfglyphtounicode{twelveparen}{247F} \pdfglyphtounicode{twelveperiod}{2493} \pdfglyphtounicode{twelveroman}{217B} \pdfglyphtounicode{twentycircle}{2473} \pdfglyphtounicode{twentyhangzhou}{5344} \pdfglyphtounicode{twentyparen}{2487} \pdfglyphtounicode{twentyperiod}{249B} \pdfglyphtounicode{two}{0032} \pdfglyphtounicode{twoarabic}{0662} \pdfglyphtounicode{twobengali}{09E8} \pdfglyphtounicode{twocircle}{2461} \pdfglyphtounicode{twocircleinversesansserif}{278B} \pdfglyphtounicode{twodeva}{0968} \pdfglyphtounicode{twodotenleader}{2025} \pdfglyphtounicode{twodotleader}{2025} \pdfglyphtounicode{twodotleadervertical}{FE30} \pdfglyphtounicode{twogujarati}{0AE8} \pdfglyphtounicode{twogurmukhi}{0A68} \pdfglyphtounicode{twohackarabic}{0662} \pdfglyphtounicode{twohangzhou}{3022} \pdfglyphtounicode{twoideographicparen}{3221} \pdfglyphtounicode{twoinferior}{2082} \pdfglyphtounicode{twomonospace}{FF12} \pdfglyphtounicode{twonumeratorbengali}{09F5} \pdfglyphtounicode{twooldstyle}{0032} \pdfglyphtounicode{twoparen}{2475} \pdfglyphtounicode{twoperiod}{2489} \pdfglyphtounicode{twopersian}{06F2} \pdfglyphtounicode{tworoman}{2171} \pdfglyphtounicode{twostroke}{01BB} \pdfglyphtounicode{twosuperior}{00B2} \pdfglyphtounicode{twothai}{0E52} \pdfglyphtounicode{twothirds}{2154} \pdfglyphtounicode{u}{0075} \pdfglyphtounicode{uacute}{00FA} \pdfglyphtounicode{ubar}{0289} \pdfglyphtounicode{ubengali}{0989} \pdfglyphtounicode{ubopomofo}{3128} \pdfglyphtounicode{ubreve}{016D} \pdfglyphtounicode{ucaron}{01D4} \pdfglyphtounicode{ucircle}{24E4} \pdfglyphtounicode{ucircumflex}{00FB} \pdfglyphtounicode{ucircumflexbelow}{1E77} \pdfglyphtounicode{ucyrillic}{0443} \pdfglyphtounicode{udattadeva}{0951} \pdfglyphtounicode{udblacute}{0171} \pdfglyphtounicode{udblgrave}{0215} \pdfglyphtounicode{udeva}{0909} \pdfglyphtounicode{udieresis}{00FC} \pdfglyphtounicode{udieresisacute}{01D8} \pdfglyphtounicode{udieresisbelow}{1E73} \pdfglyphtounicode{udieresiscaron}{01DA} \pdfglyphtounicode{udieresiscyrillic}{04F1} \pdfglyphtounicode{udieresisgrave}{01DC} \pdfglyphtounicode{udieresismacron}{01D6} \pdfglyphtounicode{udotbelow}{1EE5} \pdfglyphtounicode{ugrave}{00F9} \pdfglyphtounicode{ugujarati}{0A89} \pdfglyphtounicode{ugurmukhi}{0A09} \pdfglyphtounicode{uhiragana}{3046} \pdfglyphtounicode{uhookabove}{1EE7} \pdfglyphtounicode{uhorn}{01B0} \pdfglyphtounicode{uhornacute}{1EE9} \pdfglyphtounicode{uhorndotbelow}{1EF1} \pdfglyphtounicode{uhorngrave}{1EEB} \pdfglyphtounicode{uhornhookabove}{1EED} \pdfglyphtounicode{uhorntilde}{1EEF} \pdfglyphtounicode{uhungarumlaut}{0171} \pdfglyphtounicode{uhungarumlautcyrillic}{04F3} \pdfglyphtounicode{uinvertedbreve}{0217} \pdfglyphtounicode{ukatakana}{30A6} \pdfglyphtounicode{ukatakanahalfwidth}{FF73} \pdfglyphtounicode{ukcyrillic}{0479} \pdfglyphtounicode{ukorean}{315C} \pdfglyphtounicode{umacron}{016B} \pdfglyphtounicode{umacroncyrillic}{04EF} \pdfglyphtounicode{umacrondieresis}{1E7B} \pdfglyphtounicode{umatragurmukhi}{0A41} \pdfglyphtounicode{umonospace}{FF55} \pdfglyphtounicode{underscore}{005F} \pdfglyphtounicode{underscoredbl}{2017} \pdfglyphtounicode{underscoremonospace}{FF3F} \pdfglyphtounicode{underscorevertical}{FE33} \pdfglyphtounicode{underscorewavy}{FE4F} \pdfglyphtounicode{union}{222A} \pdfglyphtounicode{uniondbl}{22D3} \pdfglyphtounicode{unionmulti}{228E} \pdfglyphtounicode{unionsq}{2294} \pdfglyphtounicode{universal}{2200} \pdfglyphtounicode{uogonek}{0173} \pdfglyphtounicode{uparen}{24B0} \pdfglyphtounicode{upblock}{2580} \pdfglyphtounicode{upperdothebrew}{05C4} \pdfglyphtounicode{uprise}{22CF} \pdfglyphtounicode{upsilon}{03C5} \pdfglyphtounicode{upsilondieresis}{03CB} \pdfglyphtounicode{upsilondieresistonos}{03B0} \pdfglyphtounicode{upsilonlatin}{028A} \pdfglyphtounicode{upsilontonos}{03CD} \pdfglyphtounicode{upslope}{29F8} \pdfglyphtounicode{uptackbelowcmb}{031D} \pdfglyphtounicode{uptackmod}{02D4} \pdfglyphtounicode{uragurmukhi}{0A73} \pdfglyphtounicode{uring}{016F} \pdfglyphtounicode{ushortcyrillic}{045E} \pdfglyphtounicode{usmallhiragana}{3045} \pdfglyphtounicode{usmallkatakana}{30A5} \pdfglyphtounicode{usmallkatakanahalfwidth}{FF69} \pdfglyphtounicode{ustraightcyrillic}{04AF} \pdfglyphtounicode{ustraightstrokecyrillic}{04B1} \pdfglyphtounicode{utilde}{0169} \pdfglyphtounicode{utildeacute}{1E79} \pdfglyphtounicode{utildebelow}{1E75} \pdfglyphtounicode{uubengali}{098A} \pdfglyphtounicode{uudeva}{090A} \pdfglyphtounicode{uugujarati}{0A8A} \pdfglyphtounicode{uugurmukhi}{0A0A} \pdfglyphtounicode{uumatragurmukhi}{0A42} \pdfglyphtounicode{uuvowelsignbengali}{09C2} \pdfglyphtounicode{uuvowelsigndeva}{0942} \pdfglyphtounicode{uuvowelsigngujarati}{0AC2} \pdfglyphtounicode{uvowelsignbengali}{09C1} \pdfglyphtounicode{uvowelsigndeva}{0941} \pdfglyphtounicode{uvowelsigngujarati}{0AC1} \pdfglyphtounicode{v}{0076} \pdfglyphtounicode{vadeva}{0935} \pdfglyphtounicode{vagujarati}{0AB5} \pdfglyphtounicode{vagurmukhi}{0A35} \pdfglyphtounicode{vakatakana}{30F7} \pdfglyphtounicode{vav}{05D5} \pdfglyphtounicode{vavdagesh}{FB35} \pdfglyphtounicode{vavdagesh65}{FB35} \pdfglyphtounicode{vavdageshhebrew}{FB35} \pdfglyphtounicode{vavhebrew}{05D5} \pdfglyphtounicode{vavholam}{FB4B} \pdfglyphtounicode{vavholamhebrew}{FB4B} \pdfglyphtounicode{vavvavhebrew}{05F0} \pdfglyphtounicode{vavyodhebrew}{05F1} \pdfglyphtounicode{vcircle}{24E5} \pdfglyphtounicode{vdotbelow}{1E7F} \pdfglyphtounicode{vector}{20D7} \pdfglyphtounicode{vecyrillic}{0432} \pdfglyphtounicode{veharabic}{06A4} \pdfglyphtounicode{vehfinalarabic}{FB6B} \pdfglyphtounicode{vehinitialarabic}{FB6C} \pdfglyphtounicode{vehmedialarabic}{FB6D} \pdfglyphtounicode{vekatakana}{30F9} \pdfglyphtounicode{venus}{2640} \pdfglyphtounicode{verticalbar}{007C} \pdfglyphtounicode{verticallineabovecmb}{030D} \pdfglyphtounicode{verticallinebelowcmb}{0329} \pdfglyphtounicode{verticallinelowmod}{02CC} \pdfglyphtounicode{verticallinemod}{02C8} \pdfglyphtounicode{vewarmenian}{057E} \pdfglyphtounicode{vhook}{028B} \pdfglyphtounicode{vikatakana}{30F8} \pdfglyphtounicode{viramabengali}{09CD} \pdfglyphtounicode{viramadeva}{094D} \pdfglyphtounicode{viramagujarati}{0ACD} \pdfglyphtounicode{visargabengali}{0983} \pdfglyphtounicode{visargadeva}{0903} \pdfglyphtounicode{visargagujarati}{0A83} \pdfglyphtounicode{visiblespace}{2423} \pdfglyphtounicode{visualspace}{2423} \pdfglyphtounicode{vmonospace}{FF56} \pdfglyphtounicode{voarmenian}{0578} \pdfglyphtounicode{voicediterationhiragana}{309E} \pdfglyphtounicode{voicediterationkatakana}{30FE} \pdfglyphtounicode{voicedmarkkana}{309B} \pdfglyphtounicode{voicedmarkkanahalfwidth}{FF9E} \pdfglyphtounicode{vokatakana}{30FA} \pdfglyphtounicode{vparen}{24B1} \pdfglyphtounicode{vtilde}{1E7D} \pdfglyphtounicode{vturned}{028C} \pdfglyphtounicode{vuhiragana}{3094} \pdfglyphtounicode{vukatakana}{30F4} \pdfglyphtounicode{w}{0077} \pdfglyphtounicode{wacute}{1E83} \pdfglyphtounicode{waekorean}{3159} \pdfglyphtounicode{wahiragana}{308F} \pdfglyphtounicode{wakatakana}{30EF} \pdfglyphtounicode{wakatakanahalfwidth}{FF9C} \pdfglyphtounicode{wakorean}{3158} \pdfglyphtounicode{wasmallhiragana}{308E} \pdfglyphtounicode{wasmallkatakana}{30EE} \pdfglyphtounicode{wattosquare}{3357} \pdfglyphtounicode{wavedash}{301C} \pdfglyphtounicode{wavyunderscorevertical}{FE34} \pdfglyphtounicode{wawarabic}{0648} \pdfglyphtounicode{wawfinalarabic}{FEEE} \pdfglyphtounicode{wawhamzaabovearabic}{0624} \pdfglyphtounicode{wawhamzaabovefinalarabic}{FE86} \pdfglyphtounicode{wbsquare}{33DD} \pdfglyphtounicode{wcircle}{24E6} \pdfglyphtounicode{wcircumflex}{0175} \pdfglyphtounicode{wdieresis}{1E85} \pdfglyphtounicode{wdotaccent}{1E87} \pdfglyphtounicode{wdotbelow}{1E89} \pdfglyphtounicode{wehiragana}{3091} \pdfglyphtounicode{weierstrass}{2118} \pdfglyphtounicode{wekatakana}{30F1} \pdfglyphtounicode{wekorean}{315E} \pdfglyphtounicode{weokorean}{315D} \pdfglyphtounicode{wgrave}{1E81} \pdfglyphtounicode{whitebullet}{25E6} \pdfglyphtounicode{whitecircle}{25CB} \pdfglyphtounicode{whitecircleinverse}{25D9} \pdfglyphtounicode{whitecornerbracketleft}{300E} \pdfglyphtounicode{whitecornerbracketleftvertical}{FE43} \pdfglyphtounicode{whitecornerbracketright}{300F} \pdfglyphtounicode{whitecornerbracketrightvertical}{FE44} \pdfglyphtounicode{whitediamond}{25C7} \pdfglyphtounicode{whitediamondcontainingblacksmalldiamond}{25C8} \pdfglyphtounicode{whitedownpointingsmalltriangle}{25BF} \pdfglyphtounicode{whitedownpointingtriangle}{25BD} \pdfglyphtounicode{whiteleftpointingsmalltriangle}{25C3} \pdfglyphtounicode{whiteleftpointingtriangle}{25C1} \pdfglyphtounicode{whitelenticularbracketleft}{3016} \pdfglyphtounicode{whitelenticularbracketright}{3017} \pdfglyphtounicode{whiterightpointingsmalltriangle}{25B9} \pdfglyphtounicode{whiterightpointingtriangle}{25B7} \pdfglyphtounicode{whitesmallsquare}{25AB} \pdfglyphtounicode{whitesmilingface}{263A} \pdfglyphtounicode{whitesquare}{25A1} \pdfglyphtounicode{whitestar}{2606} \pdfglyphtounicode{whitetelephone}{260F} \pdfglyphtounicode{whitetortoiseshellbracketleft}{3018} \pdfglyphtounicode{whitetortoiseshellbracketright}{3019} \pdfglyphtounicode{whiteuppointingsmalltriangle}{25B5} \pdfglyphtounicode{whiteuppointingtriangle}{25B3} \pdfglyphtounicode{wihiragana}{3090} \pdfglyphtounicode{wikatakana}{30F0} \pdfglyphtounicode{wikorean}{315F} \pdfglyphtounicode{wmonospace}{FF57} \pdfglyphtounicode{wohiragana}{3092} \pdfglyphtounicode{wokatakana}{30F2} \pdfglyphtounicode{wokatakanahalfwidth}{FF66} \pdfglyphtounicode{won}{20A9} \pdfglyphtounicode{wonmonospace}{FFE6} \pdfglyphtounicode{wowaenthai}{0E27} \pdfglyphtounicode{wparen}{24B2} \pdfglyphtounicode{wreathproduct}{2240} \pdfglyphtounicode{wring}{1E98} \pdfglyphtounicode{wsuperior}{02B7} \pdfglyphtounicode{wturned}{028D} \pdfglyphtounicode{wynn}{01BF} \pdfglyphtounicode{x}{0078} \pdfglyphtounicode{xabovecmb}{033D} \pdfglyphtounicode{xbopomofo}{3112} \pdfglyphtounicode{xcircle}{24E7} \pdfglyphtounicode{xdieresis}{1E8D} \pdfglyphtounicode{xdotaccent}{1E8B} \pdfglyphtounicode{xeharmenian}{056D} \pdfglyphtounicode{xi}{03BE} \pdfglyphtounicode{xmonospace}{FF58} \pdfglyphtounicode{xparen}{24B3} \pdfglyphtounicode{xsuperior}{02E3} \pdfglyphtounicode{y}{0079} \pdfglyphtounicode{yaadosquare}{334E} \pdfglyphtounicode{yabengali}{09AF} \pdfglyphtounicode{yacute}{00FD} \pdfglyphtounicode{yadeva}{092F} \pdfglyphtounicode{yaekorean}{3152} \pdfglyphtounicode{yagujarati}{0AAF} \pdfglyphtounicode{yagurmukhi}{0A2F} \pdfglyphtounicode{yahiragana}{3084} \pdfglyphtounicode{yakatakana}{30E4} \pdfglyphtounicode{yakatakanahalfwidth}{FF94} \pdfglyphtounicode{yakorean}{3151} \pdfglyphtounicode{yamakkanthai}{0E4E} \pdfglyphtounicode{yasmallhiragana}{3083} \pdfglyphtounicode{yasmallkatakana}{30E3} \pdfglyphtounicode{yasmallkatakanahalfwidth}{FF6C} \pdfglyphtounicode{yatcyrillic}{0463} \pdfglyphtounicode{ycircle}{24E8} \pdfglyphtounicode{ycircumflex}{0177} \pdfglyphtounicode{ydieresis}{00FF} \pdfglyphtounicode{ydotaccent}{1E8F} \pdfglyphtounicode{ydotbelow}{1EF5} \pdfglyphtounicode{yeharabic}{064A} \pdfglyphtounicode{yehbarreearabic}{06D2} \pdfglyphtounicode{yehbarreefinalarabic}{FBAF} \pdfglyphtounicode{yehfinalarabic}{FEF2} \pdfglyphtounicode{yehhamzaabovearabic}{0626} \pdfglyphtounicode{yehhamzaabovefinalarabic}{FE8A} \pdfglyphtounicode{yehhamzaaboveinitialarabic}{FE8B} \pdfglyphtounicode{yehhamzaabovemedialarabic}{FE8C} \pdfglyphtounicode{yehinitialarabic}{FEF3} \pdfglyphtounicode{yehmedialarabic}{FEF4} \pdfglyphtounicode{yehmeeminitialarabic}{FCDD} \pdfglyphtounicode{yehmeemisolatedarabic}{FC58} \pdfglyphtounicode{yehnoonfinalarabic}{FC94} \pdfglyphtounicode{yehthreedotsbelowarabic}{06D1} \pdfglyphtounicode{yekorean}{3156} \pdfglyphtounicode{yen}{00A5} \pdfglyphtounicode{yenmonospace}{FFE5} \pdfglyphtounicode{yeokorean}{3155} \pdfglyphtounicode{yeorinhieuhkorean}{3186} \pdfglyphtounicode{yerahbenyomohebrew}{05AA} \pdfglyphtounicode{yerahbenyomolefthebrew}{05AA} \pdfglyphtounicode{yericyrillic}{044B} \pdfglyphtounicode{yerudieresiscyrillic}{04F9} \pdfglyphtounicode{yesieungkorean}{3181} \pdfglyphtounicode{yesieungpansioskorean}{3183} \pdfglyphtounicode{yesieungsioskorean}{3182} \pdfglyphtounicode{yetivhebrew}{059A} \pdfglyphtounicode{ygrave}{1EF3} \pdfglyphtounicode{yhook}{01B4} \pdfglyphtounicode{yhookabove}{1EF7} \pdfglyphtounicode{yiarmenian}{0575} \pdfglyphtounicode{yicyrillic}{0457} \pdfglyphtounicode{yikorean}{3162} \pdfglyphtounicode{yinyang}{262F} \pdfglyphtounicode{yiwnarmenian}{0582} \pdfglyphtounicode{ymonospace}{FF59} \pdfglyphtounicode{yod}{05D9} \pdfglyphtounicode{yoddagesh}{FB39} \pdfglyphtounicode{yoddageshhebrew}{FB39} \pdfglyphtounicode{yodhebrew}{05D9} \pdfglyphtounicode{yodyodhebrew}{05F2} \pdfglyphtounicode{yodyodpatahhebrew}{FB1F} \pdfglyphtounicode{yohiragana}{3088} \pdfglyphtounicode{yoikorean}{3189} \pdfglyphtounicode{yokatakana}{30E8} \pdfglyphtounicode{yokatakanahalfwidth}{FF96} \pdfglyphtounicode{yokorean}{315B} \pdfglyphtounicode{yosmallhiragana}{3087} \pdfglyphtounicode{yosmallkatakana}{30E7} \pdfglyphtounicode{yosmallkatakanahalfwidth}{FF6E} \pdfglyphtounicode{yotgreek}{03F3} \pdfglyphtounicode{yoyaekorean}{3188} \pdfglyphtounicode{yoyakorean}{3187} \pdfglyphtounicode{yoyakthai}{0E22} \pdfglyphtounicode{yoyingthai}{0E0D} \pdfglyphtounicode{yparen}{24B4} \pdfglyphtounicode{ypogegrammeni}{037A} \pdfglyphtounicode{ypogegrammenigreekcmb}{0345} \pdfglyphtounicode{yr}{01A6} \pdfglyphtounicode{yring}{1E99} \pdfglyphtounicode{ysuperior}{02B8} \pdfglyphtounicode{ytilde}{1EF9} \pdfglyphtounicode{yturned}{028E} \pdfglyphtounicode{yuhiragana}{3086} \pdfglyphtounicode{yuikorean}{318C} \pdfglyphtounicode{yukatakana}{30E6} \pdfglyphtounicode{yukatakanahalfwidth}{FF95} \pdfglyphtounicode{yukorean}{3160} \pdfglyphtounicode{yusbigcyrillic}{046B} \pdfglyphtounicode{yusbigiotifiedcyrillic}{046D} \pdfglyphtounicode{yuslittlecyrillic}{0467} \pdfglyphtounicode{yuslittleiotifiedcyrillic}{0469} \pdfglyphtounicode{yusmallhiragana}{3085} \pdfglyphtounicode{yusmallkatakana}{30E5} \pdfglyphtounicode{yusmallkatakanahalfwidth}{FF6D} \pdfglyphtounicode{yuyekorean}{318B} \pdfglyphtounicode{yuyeokorean}{318A} \pdfglyphtounicode{yyabengali}{09DF} \pdfglyphtounicode{yyadeva}{095F} \pdfglyphtounicode{z}{007A} \pdfglyphtounicode{zaarmenian}{0566} \pdfglyphtounicode{zacute}{017A} \pdfglyphtounicode{zadeva}{095B} \pdfglyphtounicode{zagurmukhi}{0A5B} \pdfglyphtounicode{zaharabic}{0638} \pdfglyphtounicode{zahfinalarabic}{FEC6} \pdfglyphtounicode{zahinitialarabic}{FEC7} \pdfglyphtounicode{zahiragana}{3056} \pdfglyphtounicode{zahmedialarabic}{FEC8} \pdfglyphtounicode{zainarabic}{0632} \pdfglyphtounicode{zainfinalarabic}{FEB0} \pdfglyphtounicode{zakatakana}{30B6} \pdfglyphtounicode{zaqefgadolhebrew}{0595} \pdfglyphtounicode{zaqefqatanhebrew}{0594} \pdfglyphtounicode{zarqahebrew}{0598} \pdfglyphtounicode{zayin}{05D6} \pdfglyphtounicode{zayindagesh}{FB36} \pdfglyphtounicode{zayindageshhebrew}{FB36} \pdfglyphtounicode{zayinhebrew}{05D6} \pdfglyphtounicode{zbopomofo}{3117} \pdfglyphtounicode{zcaron}{017E} \pdfglyphtounicode{zcircle}{24E9} \pdfglyphtounicode{zcircumflex}{1E91} \pdfglyphtounicode{zcurl}{0291} \pdfglyphtounicode{zdot}{017C} \pdfglyphtounicode{zdotaccent}{017C} \pdfglyphtounicode{zdotbelow}{1E93} \pdfglyphtounicode{zecyrillic}{0437} \pdfglyphtounicode{zedescendercyrillic}{0499} \pdfglyphtounicode{zedieresiscyrillic}{04DF} \pdfglyphtounicode{zehiragana}{305C} \pdfglyphtounicode{zekatakana}{30BC} \pdfglyphtounicode{zero}{0030} \pdfglyphtounicode{zeroarabic}{0660} \pdfglyphtounicode{zerobengali}{09E6} \pdfglyphtounicode{zerodeva}{0966} \pdfglyphtounicode{zerogujarati}{0AE6} \pdfglyphtounicode{zerogurmukhi}{0A66} \pdfglyphtounicode{zerohackarabic}{0660} \pdfglyphtounicode{zeroinferior}{2080} \pdfglyphtounicode{zeromonospace}{FF10} \pdfglyphtounicode{zerooldstyle}{0030} \pdfglyphtounicode{zeropersian}{06F0} \pdfglyphtounicode{zerosuperior}{2070} \pdfglyphtounicode{zerothai}{0E50} \pdfglyphtounicode{zerowidthjoiner}{FEFF} \pdfglyphtounicode{zerowidthnonjoiner}{200C} \pdfglyphtounicode{zerowidthspace}{200B} \pdfglyphtounicode{zeta}{03B6} \pdfglyphtounicode{zhbopomofo}{3113} \pdfglyphtounicode{zhearmenian}{056A} \pdfglyphtounicode{zhebrevecyrillic}{04C2} \pdfglyphtounicode{zhecyrillic}{0436} \pdfglyphtounicode{zhedescendercyrillic}{0497} \pdfglyphtounicode{zhedieresiscyrillic}{04DD} \pdfglyphtounicode{zihiragana}{3058} \pdfglyphtounicode{zikatakana}{30B8} \pdfglyphtounicode{zinorhebrew}{05AE} \pdfglyphtounicode{zlinebelow}{1E95} \pdfglyphtounicode{zmonospace}{FF5A} \pdfglyphtounicode{zohiragana}{305E} \pdfglyphtounicode{zokatakana}{30BE} \pdfglyphtounicode{zparen}{24B5} \pdfglyphtounicode{zretroflexhook}{0290} \pdfglyphtounicode{zstroke}{01B6} \pdfglyphtounicode{zuhiragana}{305A} \pdfglyphtounicode{zukatakana}{30BA} lcdf-typetools-2.108/INSTALL0000664000175000017500000001644612732752520012470 00000000000000Basic Installation ================== These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, a file `config.cache' that saves the results of its tests to speed up reconfiguring, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.in' is used to create `configure' by a program called `autoconf'. You only need `configure.in' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. You can give `configure' initial values for variables by setting them in the environment. Using a Bourne-compatible shell, you can do that on the command line like this: CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure Or on systems that have the `env' program, you can do it like this: env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not supports the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH', the package will use PATH as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' can not figure out automatically, but needs to determine by the type of host the package will run on. Usually `configure' can figure that out, but if it prints a message saying it can not guess the host type, give it the `--host=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name with three fields: CPU-COMPANY-SYSTEM See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the host type. If you are building compiler tools for cross-compiling, you can also use the `--target=TYPE' option to select the type of system they will produce code for and the `--build=TYPE' option to select the type of system on which you are compiling the package. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Operation Controls ================== `configure' recognizes the following options to control how it operates. `--cache-file=FILE' Use and save the results of the tests in FILE instead of `./config.cache'. Set FILE to `/dev/null' to disable caching, for debugging `configure'. `--help' Print a summary of the options to `configure', and exit. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--version' Print the version of Autoconf used to generate the `configure' script, and exit. `configure' also accepts some other, not widely useful, options. lcdf-typetools-2.108/t1testpage/0000755000175000017500000000000013423377073013567 500000000000000lcdf-typetools-2.108/t1testpage/t1testpage.10000644000175000017500000000303313423376706015653 00000000000000.ds V 2.108 .de M .BR "\\$1" "(\\$2)\\$3" .. .de Sp .if n .sp .if t .sp 0.4 .. .TH T1TESTPAGE 1 "LCDF Typetools" "Version \*V" .SH NAME t1testpage \- create a PostScript proof for a Type 1 font .SH SYNOPSIS .B t1testpage \%[\fIfont...\fR] .SH DESCRIPTION .BR T1testpage creates a PostScript proof document for the specified Type 1 font file and writes it to the standard output. The proof shows every glyph in the font, including its glyph name and encoding. The .I font argument should be the name of a PFA or PFB font file. If more than one .I font is given, the output proof contains all the fonts in order. If .I font is omitted, t1testpage will read a font file from the standard input. .PP T1testpage is preliminary software. ' .SH OPTIONS .PD 0 .TP 5 .BR \-g " \fIglyphs\fR, " \-\-glyph= \fIglyphs Print only glyphs matching .IR glyphs . The argument is a glyph pattern, using shell-like matching rules; thus, .BR "\-g " 'A*' will match the glyphs 'A', 'Atilde', and 'Ampersand', among others. You can give this option multiple times, or supply multiple space-separated patterns in a single option. ' .Sp .TP 5 .BR \-s ", " \-\-smoke Print smoke proofs, one glyph per page. This option is preliminary. ' .Sp .TP 5 .BR \-o " \fIfile\fR, " \-\-output= \fIfile Write the output proof to .I file instead of the standard output. ' .Sp .TP 5 .BR \-h ", " \-\-help Print usage information and exit. ' .Sp .TP 5 .BR \-v ", " \-\-version Print the version number and some short non-warranty information and exit. .PD ' .SH AUTHOR Eddie Kohler (ekohler@gmail.com) lcdf-typetools-2.108/t1testpage/t1testpage.cc0000644000175000017500000005050213423375330016073 00000000000000/* t1testpage.cc -- driver for generating Type 1 fonts' test pages * * Copyright (c) 1999-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_CTIME # include #endif #if defined(_MSDOS) || defined(_WIN32) # include # include #endif using namespace Efont; #define VERSION_OPT 301 #define HELP_OPT 302 #define OUTPUT_OPT 303 #define GLYPH_OPT 304 #define SMOKE_OPT 305 const Clp_Option options[] = { { "help", 'h', HELP_OPT, 0, 0 }, { "output", 'o', OUTPUT_OPT, Clp_ValString, 0 }, { "version", 0, VERSION_OPT, 0, 0 }, { "glyph", 'g', GLYPH_OPT, Clp_ValString, 0 }, { "smoke", 's', SMOKE_OPT, 0, Clp_Negate } }; static const char *program_name; static PermString::Initializer initializer; static HashMap glyph_order(-1); void usage_error(ErrorHandler *errh, const char *error_message, ...) { va_list val; va_start(val, error_message); if (!error_message) errh->message("Usage: %s [OPTION]... FONT", program_name); else errh->xmessage(ErrorHandler::e_error, error_message, val); errh->message("Type %s --help for more information.", program_name); exit(1); } void usage() { FileErrorHandler uerrh(stdout); uerrh.message("\ % creates a PostScript proof document for the specified Type 1\n\ font file and writes it to the standard output. The proof shows every\n\ glyph in the font, including its glyph name and encoding.\n\ \n\ Usage: %s [OPTION]... [FONT...]\n\ \n\ Each FONT is the name of a PFA or PFB font file. If omitted, t1testpage will\n\ read a font file from the standard input.\n\ \n\ Options:\n\ -g, --glyph=GLYPH Limit output to one or more GLYPHs.\n\ -s, --smoke Print smoke proofs, one character per page.\n\ -o, --output=FILE Write output to FILE instead of standard out.\n\ -h, --help Print this message and exit.\n\ --version Print version number and exit.\n\ \n\ Report bugs to .\n", program_name); } // OUTPUTTER namespace { class Testpager { public: Testpager(FILE *f) : _f(f), _pageno(1) { } virtual ~Testpager() { fclose(_f); } virtual void prolog(const Vector &fonts) = 0; void newpage() { fprintf(_f, "%%%%Page: %d %d\n", _pageno, _pageno); ++_pageno; } virtual void font(Type1Font *font, const Vector& glyph_names) = 0; virtual void epilog() { fprintf(_f, "%%%%EOF\n"); } protected: FILE *_f; int _pageno; }; class GridTestpager : public Testpager { public: GridTestpager(FILE *f) : Testpager(f) { } void prolog(const Vector &fonts); void font(Type1Font *font, const Vector& glyph_names); }; class SmokeTestpager : public Testpager { public: SmokeTestpager(FILE *f) : Testpager(f) { } void prolog(const Vector &fonts); void font(Type1Font *font, const Vector& glyph_names); }; } // MAIN static Type1Font * do_file(const char *filename, PsresDatabase *psres, ErrorHandler *errh) { FILE *f; if (!filename || strcmp(filename, "-") == 0) { f = stdin; filename = ""; #if defined(_MSDOS) || defined(_WIN32) _setmode(_fileno(f), _O_BINARY); #endif } else f = fopen(filename, "rb"); if (!f) { // check for PostScript name Filename fn = psres->filename_value("FontOutline", filename); f = fn.open_read(); } if (!f) errh->fatal("%s: %s", filename, strerror(errno)); Type1Reader *reader; int c = getc(f); ungetc(c, f); if (c == EOF) errh->fatal("%s: empty file", filename); if (c == 128) reader = new Type1PFBReader(f); else reader = new Type1PFAReader(f); Type1Font *font = new Type1Font(*reader); delete reader; return font; } void GridTestpager::prolog(const Vector &fonts) { fprintf(_f, "%%!PS-Adobe-3.0\n\ %%%%LanguageLevel: 2\n\ %%%%DocumentMedia: Plain 612 792 white ( )\n\ %%%%BeginProlog\n"); fprintf(_f, "/magicstr 1 string def\n\ /magicbox { %% row col char name encoding magicbox -\n\ 5 3 roll 54 mul 36 add exch 54 mul neg 682 add moveto currentpoint\n\ .8 setgray 54 0 rlineto 0 54 rlineto -54 0 rlineto closepath stroke\n\ 0 setgray moveto\n\ gsave /Helvetica 7 selectfont 3 1.5 rmoveto show grestore\n\ gsave /Helvetica 7 selectfont 3 45.5 rmoveto show grestore\n\ magicstr 0 3 -1 roll put\n\ magicstr stringwidth pop 54 sub -2 div 16 rmoveto magicstr show\n\ } bind def\n"); Type1PFAWriter w(_f); for (Vector::const_iterator it = fonts.begin(); it != fonts.end(); ++it) (*it)->write(w); fprintf(_f, "%%%%EndProlog\n"); } void GridTestpager::font(Type1Font* font, const Vector& glyph_names) { HashMap encodings(-1); if (Type1Encoding *encoding = font->type1_encoding()) for (int i = 255; i >= 0; i--) if (encoding->elt(i)) encodings.insert(encoding->elt(i), i); int per_row = 10; int nrows = 13; int per_page = nrows * per_row; int page = 0, gi = -1; for (Vector::const_iterator it = glyph_names.begin(); it != glyph_names.end(); ++it) { // allow font that doesn't have all glyphs if (!font->glyph(*it)) continue; ++gi; if (gi % per_page == 0) { if (page) fprintf(_f, "showpage restore\n"); ++page; newpage(); fprintf(_f, "save\n"); // make new font fprintf(_f, "/%s findfont dup length dict begin\n\ { 1 index /FID ne {def} {pop pop} ifelse } forall\n /Encoding [", font->font_name().c_str()); int gx = 0; for (Vector::const_iterator xit = it; xit != glyph_names.end() && gx < per_page; ++xit) if (font->glyph(*xit)) { ++gx; fprintf(_f, " /%s", xit->c_str()); if (gx % 10 == 9) fprintf(_f, "\n"); } fprintf(_f, " ] def\n currentdict end /X exch definefont pop\n\ /Helvetica-Bold 16 selectfont 36 742 moveto (%s) show\n\ /X 24 selectfont\n", font->font_name().c_str()); } int row = (gi % per_page) / per_row; int col = gi % per_row; fprintf(_f, "%d %d %d (%s)", row, col, gi % per_page, it->c_str()); if (encodings[*it] >= 0) { int e = encodings[*it]; if (e == '\\') fprintf(_f, " ('\\\\\\\\')"); else if (e == '\'') fprintf(_f, " ('\\\\'')"); else if (e == '(' || e == ')') fprintf(_f, " ('\\%c')", e); else if (e >= 32 && e < 127) fprintf(_f, " ('%c')", e); else fprintf(_f, " ('\\\\%03o')", e); } else fprintf(_f, " ()"); fprintf(_f, " magicbox\n"); } if (page) fprintf(_f, "showpage restore\n"); } /***** * SMOKE PROOFS **/ inline StringAccum& operator<<(StringAccum& sa, const Point& p) { return sa << p.x << ' ' << p.y; } class Smoker : public CharstringInterp { public: Smoker(const Transform&); void act_line(int, const Point &, const Point &); void act_curve(int, const Point &, const Point &, const Point &, const Point &); void act_closepath(int); String char_postscript() { return _char_sa.take_string(); } String points_postscript() { return _points_sa.take_string(); } bool run(const CharstringContext&); private: Transform _xform; StringAccum _char_sa; StringAccum _points_sa; Point _char_cp; inline void maybe_move(const Point&); }; Smoker::Smoker(const Transform& xform) : _xform(xform) { } void Smoker::maybe_move(const Point& p) { if (_char_cp.x < -100000 || _char_cp != p) { _char_sa << (p * _xform) << " moveto\n"; _points_sa << (p * _xform) << " pA\n"; } } void Smoker::act_line(int cmd, const Point& p0, const Point& p1) { Point xp1 = p1 * _xform; maybe_move(p0); _char_sa << xp1 << " lineto\n"; if (cmd == Charstring::cRlineto || cmd == Charstring::cHlineto || cmd == Charstring::cVlineto) _points_sa << xp1 << " pA\n"; _char_cp = p1; } void Smoker::act_curve(int, const Point &p0, const Point &p1, const Point &p2, const Point &p3) { Point xp1 = p1 * _xform; Point xp2 = p2 * _xform; Point xp3 = p3 * _xform; maybe_move(p0); _char_sa << xp1 << ' ' << xp2 << ' ' << xp3 << " curveto\n"; _points_sa << xp1 << " pC " << xp2 << " pC " << xp3 << " pA\n"; _char_cp = p3; } void Smoker::act_closepath(int) { _char_sa << "closepath\n"; } bool Smoker::run(const CharstringContext& g) { _char_sa.clear(); _points_sa.clear(); _char_cp.x = -200000; return CharstringInterp::interpret(g); } #define LEFT_BOUND 72. #define RIGHT_BOUND (7.5 * 72) #define BOTTOM_BOUND 72. #define TOP_BOUND (7.5 * 72) static Transform bounds2xform(CharstringBounds& bounds, bool expand = false) { if (expand) { Point vec = bounds.bb_top_right() - bounds.bb_bottom_left(); bounds.act_line(0, bounds.bb_bottom_left() - 0.1 * vec, bounds.bb_top_right() + 0.1 * vec); } bounds.act_line(0, Point(0, 0), bounds.width()); bounds.act_line(0, Point(0, 0), Point(1, 1)); double true_width = std::max(bounds.bb_right(), 0.) - std::min(bounds.bb_left(), 0.); double true_height = std::max(bounds.bb_top(), 0.) - std::min(bounds.bb_bottom(), 0.); double x_scale = (RIGHT_BOUND - LEFT_BOUND) / true_width; double y_scale = (TOP_BOUND - BOTTOM_BOUND) / true_height; double scale = std::min(x_scale, y_scale); double origin_x = LEFT_BOUND; if (bounds.bb_left() < 0) origin_x += -bounds.bb_left() * scale; double origin_y = BOTTOM_BOUND; if (bounds.bb_bottom() < 0) origin_y += -bounds.bb_bottom() * scale; return Transform(scale, 0, 0, scale, origin_x, origin_y); } static const char* const bounds_glyphs[] = { "A", "Eacute", "Ecircumflex", "l", "g", "p", "q", "j", "J", "emdash", 0 }; void SmokeTestpager::prolog(const Vector &) { fprintf(_f, "%%!PS-Adobe-3.0\n%%%%LanguageLevel: 2\n%%%%BeginProlog\n"); fprintf(_f, "/pA { %% x y pA -\n\ moveto\n\ -2 -2 rmoveto 4 0 rlineto 0 4 rlineto -4 0 rlineto closepath\n\ gsave 1 setgray stroke grestore 0 setgray fill\n\ } bind def\n\ /pC { %% x y pC -\n\ 2 copy moveto 2 0 rmoveto 2 0 360 arc\n\ gsave 1 setgray stroke grestore 0.1 setgray fill\n\ } bind def\n\ "); fprintf(_f, "%%%%EndProlog\n"); } void SmokeTestpager::font(Type1Font* font, const Vector& glyph_names) { HashMap encodings(-1); if (Type1Encoding *encoding = font->type1_encoding()) for (int i = 255; i >= 0; i--) encodings.insert(encoding->elt(i), i); // First, calculate font bounds, and from there, the transform. CharstringBounds bounds; for (const char* const* bg = bounds_glyphs; *bg; bg++) if (CharstringContext cc = font->glyph_context(*bg)) bounds.char_bounds(cc, false); if (bounds.bb_left() == bounds.bb_right()) for (int gi = 0; gi < glyph_names.size(); gi++) bounds.char_bounds(font->glyph_context(glyph_names[gi]), false); Transform font_xform = bounds2xform(bounds, true); for (int gi = 0; gi < glyph_names.size(); gi++) { // allow font that doesn't have all glyphs if (!font->glyph(glyph_names[gi])) continue; newpage(); fprintf(_f, "save\n"); CharstringContext cc = font->glyph_context(glyph_names[gi]); bounds.clear(); bounds.char_bounds(cc, false); Transform xform(font_xform); if (bounds.bb_known()) { Point lb = bounds.bb_bottom_left() * xform; Point rt = bounds.bb_top_right() * xform; Point wd = bounds.width() * xform; if (lb.x < LEFT_BOUND || lb.y < BOTTOM_BOUND || rt.x > RIGHT_BOUND || rt.y > TOP_BOUND || wd.x < LEFT_BOUND || wd.x > RIGHT_BOUND || wd.y < BOTTOM_BOUND || wd.y > TOP_BOUND) xform = bounds2xform(bounds); } Smoker smoker(xform); smoker.run(font->glyph_context(glyph_names[gi])); fprintf(_f, "%g %g moveto 0 %g rlineto %g %g moveto 0 %g rlineto %g %g moveto %g 0 rlineto 0 setgray stroke\n", (Point(0, 0) * xform).x, BOTTOM_BOUND - 36, TOP_BOUND - BOTTOM_BOUND + 72, (bounds.width() * xform).x, BOTTOM_BOUND - 36, TOP_BOUND - BOTTOM_BOUND + 72, LEFT_BOUND - 36, (Point(0, 0) * xform).y, RIGHT_BOUND - LEFT_BOUND + 72); fprintf(_f, "%s\n0.5 setgray fill\n\n1 setlinewidth\n%s\nshowpage\nrestore\n", smoker.char_postscript().c_str(), smoker.points_postscript().c_str()); } } /***** * MAIN PROGRAM **/ int click_strcmp(PermString a, PermString b) { const char *ad = a.c_str(), *ae = a.c_str() + a.length(); const char *bd = b.c_str(), *be = b.c_str() + b.length(); while (ad < ae && bd < be) { if (isdigit((unsigned char) *ad) && isdigit((unsigned char) *bd)) { // compare the two numbers, but don't treat them as numbers in // case of overflow // first, skip initial '0's const char *iad = ad, *ibd = bd; while (ad < ae && *ad == '0') ad++; while (bd < be && *bd == '0') bd++; int longer_zeros = (ad - iad) - (bd - ibd); // skip to end of number const char *nad = ad, *nbd = bd; while (ad < ae && isdigit((unsigned char) *ad)) ad++; while (bd < be && isdigit((unsigned char) *bd)) bd++; // longer number must be larger if ((ad - nad) != (bd - nbd)) return (ad - nad) - (bd - nbd); // otherwise, compare numbers with the same length for (; nad < ad && nbd < bd; nad++, nbd++) if (*nad != *nbd) return *nad - *nbd; // finally, longer string of initial '0's wins if (longer_zeros != 0) return longer_zeros; } else if (isdigit((unsigned char) *ad)) return (isalpha((unsigned char) *bd) ? -1 : 1); else if (isdigit((unsigned char) *bd)) return (isalpha((unsigned char) *ad) ? 1 : -1); else { int d = tolower((unsigned char) *ad) - tolower((unsigned char) *bd); if (d != 0) return d; ad++; bd++; } } if ((ae - ad) != (be - bd)) return (ae - ad) - (be - bd); else { assert(a.length() == b.length()); return memcmp(a.c_str(), b.c_str(), a.length()); } } extern "C" { static int CDECL glyphcompare(const void *lv, const void *rv) { const PermString* ln = (const PermString*)lv; const PermString* rn = (const PermString*)rv; // try first without the '.'s const char* ldot = strchr(ln->c_str(), '.'); const char* rdot = strchr(rn->c_str(), '.'); if (ldot == ln->begin()) ldot = 0; if (rdot == rn->begin()) rdot = 0; if (ldot || rdot) { PermString l(ln->begin(), ldot ? ldot : ln->end()); PermString r(rn->begin(), rdot ? rdot : rn->end()); int diff = glyphcompare(&l, &r); if (diff != 0) return diff; } int lorder = glyph_order[*ln]; int rorder = glyph_order[*rn]; if (lorder >= 0 && rorder >= 0) return lorder - rorder; else if (lorder >= 0) return -1; else if (rorder >= 0) return 1; else return click_strcmp(*ln, *rn); } } static bool glyph_matches(const String& glyph_name, const String* pattern_begin, const String* pattern_end) { if (pattern_begin >= pattern_end) return true; for (; pattern_begin < pattern_end; pattern_begin++) if (glob_match(glyph_name, *pattern_begin)) return true; return false; } int main(int argc, char *argv[]) { PsresDatabase *psres = new PsresDatabase; psres->add_psres_path(getenv("PSRESOURCEPATH"), 0, false); Clp_Parser *clp = Clp_NewParser(argc, (const char * const *)argv, sizeof(options) / sizeof(options[0]), options); program_name = Clp_ProgramName(clp); ErrorHandler *errh = ErrorHandler::static_initialize(new FileErrorHandler(stderr)); const char *output_file = 0; Vector glyph_patterns; bool smoke = false; Vector fonts; while (1) { int opt = Clp_Next(clp); switch (opt) { case GLYPH_OPT: { const char* s = clp->vstr, *end = s + strlen(s); while (s < end) { while (s < end && isspace((unsigned char) *s)) s++; const char* word = s; while (s < end && !isspace((unsigned char) *s)) s++; if (word < s) glyph_patterns.push_back(String(word, s - word)); } break; } case SMOKE_OPT: smoke = !clp->negated; break; case OUTPUT_OPT: if (output_file) errh->fatal("output file already specified"); output_file = clp->vstr; break; case VERSION_OPT: printf("t1testpage (LCDF typetools) %s\n", VERSION); printf("Copyright (C) 1999-2019 Eddie Kohler\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); exit(0); break; case HELP_OPT: usage(); exit(0); break; case Clp_NotOption: fonts.push_back(do_file(clp->vstr, psres, errh)); break; case Clp_Done: goto done; case Clp_BadOption: usage_error(errh, 0); break; default: break; } } done: if (!fonts.size()) fonts.push_back(do_file(0, psres, errh)); FILE *outf; if (!output_file || strcmp(output_file, "-") == 0) outf = stdout; else { outf = fopen(output_file, "w"); if (!outf) errh->fatal("%s: %s", output_file, strerror(errno)); } //font->undo_synthetic(); // Prepare glyph order table int gindex = 0; char buf[7] = "Asmall"; for (int c = 0; c < 26; c++) { buf[0] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[c]; glyph_order.insert(PermString(buf[0]), gindex++); glyph_order.insert(PermString("abcdefghijklmnopqrstuvwxyz"[c]), gindex++); glyph_order.insert(PermString(buf), gindex++); } glyph_order.insert("parenleft", gindex++); glyph_order.insert("period", gindex++); glyph_order.insert("comma", gindex++); glyph_order.insert("hyphen", gindex++); glyph_order.insert("ampersand", gindex++); glyph_order.insert("semicolon", gindex++); glyph_order.insert("exclamation", gindex++); glyph_order.insert("question", gindex++); glyph_order.insert("parenright", gindex++); glyph_order.insert("zero", gindex++); glyph_order.insert("one", gindex++); glyph_order.insert("two", gindex++); glyph_order.insert("three", gindex++); glyph_order.insert("four", gindex++); glyph_order.insert("five", gindex++); glyph_order.insert("six", gindex++); glyph_order.insert("seven", gindex++); glyph_order.insert("eight", gindex++); glyph_order.insert("nine", gindex++); glyph_order.insert("zerooldstyle", gindex++); glyph_order.insert("oneoldstyle", gindex++); glyph_order.insert("twooldstyle", gindex++); glyph_order.insert("threeoldstyle", gindex++); glyph_order.insert("fouroldstyle", gindex++); glyph_order.insert("fiveoldstyle", gindex++); glyph_order.insert("sixoldstyle", gindex++); glyph_order.insert("sevenoldstyle", gindex++); glyph_order.insert("eightoldstyle", gindex++); glyph_order.insert("nineoldstyle", gindex++); glyph_order.insert(".notdef", gindex++); glyph_order.insert("space", gindex++); // Get glyph names. HashMap glyph_hash(0); for (Vector::iterator it = fonts.begin(); it != fonts.end(); ++it) for (int i = 0; i < (*it)->nglyphs(); i++) { if (glyph_matches((*it)->glyph_name(i), glyph_patterns.begin(), glyph_patterns.end())) glyph_hash.insert((*it)->glyph_name(i), 1); } Vector glyph_names; for (HashMap::iterator it = glyph_hash.begin(); it != glyph_hash.end(); ++it) glyph_names.push_back(it.key()); if (glyph_names.size() == 0) errh->fatal("no glyphs to print"); qsort(glyph_names.begin(), glyph_names.size(), sizeof(PermString), glyphcompare); // outputs Testpager *tp; if (smoke) tp = new SmokeTestpager(outf); else tp = new GridTestpager(outf); tp->prolog(fonts); for (Vector::iterator it = fonts.begin(); it != fonts.end(); ++it) tp->font(*it, glyph_names); tp->epilog(); delete tp; exit(0); } lcdf-typetools-2.108/t1testpage/Makefile.in0000644000175000017500000005112013423376574015560 00000000000000# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : bin_PROGRAMS = t1testpage$(EXEEXT) subdir = t1testpage ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/lcdf-typetools.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/autoconf.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" PROGRAMS = $(bin_PROGRAMS) am_t1testpage_OBJECTS = t1testpage.$(OBJEXT) t1testpage_OBJECTS = $(am_t1testpage_OBJECTS) t1testpage_DEPENDENCIES = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(t1testpage_SOURCES) DIST_SOURCES = $(t1testpage_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KPATHSEA_DEPEND = @KPATHSEA_DEPEND@ KPATHSEA_INCLUDES = @KPATHSEA_INCLUDES@ KPATHSEA_LIBS = @KPATHSEA_LIBS@ KPATHSEA_RULE = @KPATHSEA_RULE@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SELECTED_SUBDIRS = @SELECTED_SUBDIRS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TEMPLATE_OBJS = @TEMPLATE_OBJS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ encdir = @encdir@ exec_prefix = @exec_prefix@ glyphlistdir = @glyphlistdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign man_MANS = t1testpage.1 t1testpage_SOURCES = t1testpage.cc t1testpage_LDADD = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_CPPFLAGS = -I$(srcdir)/../include CLEANFILES = @TEMPLATE_OBJS@ EXTRA_DIST = t1testpage.1 all: all-am .SUFFIXES: .SUFFIXES: .cc .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign t1testpage/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign t1testpage/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) t1testpage$(EXEEXT): $(t1testpage_OBJECTS) $(t1testpage_DEPENDENCIES) $(EXTRA_t1testpage_DEPENDENCIES) @rm -f t1testpage$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(t1testpage_OBJECTS) $(t1testpage_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1testpage.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-man uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-binPROGRAMS install-data install-data-am \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-man1 install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-binPROGRAMS uninstall-man uninstall-man1 .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lcdf-typetools-2.108/t1testpage/Makefile.am0000664000175000017500000000051212732752520015537 00000000000000## Process this file with automake to produce Makefile.in AUTOMAKE_OPTIONS = foreign bin_PROGRAMS = t1testpage man_MANS = t1testpage.1 t1testpage_SOURCES = t1testpage.cc t1testpage_LDADD = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_CPPFLAGS = -I$(srcdir)/../include CLEANFILES = @TEMPLATE_OBJS@ EXTRA_DIST = t1testpage.1 lcdf-typetools-2.108/COPYING0000664000175000017500000004320612732752520012464 00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. lcdf-typetools-2.108/configure0000755000175000017500000075320613423376574013357 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for lcdf-typetools 2.108. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='lcdf-typetools' PACKAGE_TARNAME='lcdf-typetools' PACKAGE_VERSION='2.108' PACKAGE_STRING='lcdf-typetools 2.108' PACKAGE_BUGREPORT='' PACKAGE_URL='' ac_unique_file="NEWS.md" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS KPATHSEA_RULE encdir glyphlistdir KPATHSEA_DEPEND KPATHSEA_LIBS KPATHSEA_INCLUDES have_kpathsea_FALSE have_kpathsea_TRUE SELECTED_SUBDIRS FIXLIBC_FALSE FIXLIBC_TRUE EGREP GREP TEMPLATE_OBJS RANLIB CXXCPP am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE ac_ct_CXX CXXFLAGS CXX CPP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC MAINT MAINTAINER_MODE_FALSE MAINTAINER_MODE_TRUE AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_maintainer_mode enable_dependency_tracking enable_warnings enable_precondition_checking enable_adobe_code enable_cfftot1 enable_mmafm enable_mmpfb enable_otfinfo enable_otftotfm enable_t1dotlessj enable_t1lint enable_t1rawafm enable_t1reencode enable_t1testpage enable_ttftotype42 enable_updmap with_kpathsea enable_selfauto_set enable_glyphlistdir enable_encdir ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP CXX CXXFLAGS CCC CXXCPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures lcdf-typetools 2.108 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/lcdf-typetools] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of lcdf-typetools 2.108:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-warnings compile with -W -Wall --enable-precondition-checking include precondition checking assertions --disable-adobe-code do not include Adobe code --disable-cfftot1 do not build the cfftot1 program --disable-mmafm do not build the mmafm program --disable-mmpfb do not build the mmpfb program --disable-otfinfo do not build the otfinfo program --disable-otftotfm do not build the otftotfm program --disable-t1dotlessj do not build the t1dotlessj program --disable-t1lint do not build the t1lint program --disable-t1rawafm do not build the t1rawafm program --disable-t1reencode do not build the t1reencode program --disable-t1testpage do not build the t1testpage program --disable-ttftotype42 do not build the ttftotype42 program --disable-auto-cfftot1 disable running cfftot1 from otftotfm --disable-auto-t1dotlessj disable running t1dotlessj from otftotfm --disable-auto-ttftotype42 disable running ttftotype42 from otftotfm --disable-auto-updmap disable running updmap from otftotfm --disable-selfauto-set disable setting SELFAUTO variables from kpsewhich --enable-glyphlistdir=DIR store glyphlist.txt files in DIR [pkgdatadir] --enable-encdir=DIR store encoding files in DIR [pkgdatadir] Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-kpathsea=PREFIX Kpathsea is installed (under PREFIX) Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor CXX C++ compiler command CXXFLAGS C++ compiler flags CXXCPP C++ preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF lcdf-typetools configure 2.108 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_cxx_try_cpp LINENO # ------------------------ # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_cxx_try_link LINENO # ------------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_link # ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES # --------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_cxx_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_mongrel # ac_fn_cxx_try_run LINENO # ------------------------ # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_cxx_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_run # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_cxx_check_decl LINENO SYMBOL VAR INCLUDES # ----------------------------------------------- # Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR # accordingly. ac_fn_cxx_check_decl () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack as_decl_name=`echo $2|sed 's/ *(.*//'` as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 $as_echo_n "checking whether $as_decl_name is declared... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { #ifndef $as_decl_name #ifdef __cplusplus (void) $as_decl_use; #else (void) $as_decl_name; #endif #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_decl # ac_fn_cxx_check_func LINENO FUNC VAR # ------------------------------------ # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_cxx_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_func # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES # -------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes # INCLUDES, setting VAR accordingly. Returns whether the value could be # computed ac_fn_c_compute_int () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=0 ac_mid=0 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid; break else as_fn_arith $ac_mid + 1 && ac_lo=$as_val if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) < 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=-1 ac_mid=-1 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=$ac_mid; break else as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid else as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in #(( ?*) eval "$3=\$ac_lo"; ac_retval=0 ;; '') ac_retval=1 ;; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 static long int longval () { return $2; } static unsigned long int ulongval () { return $2; } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (($2) < 0) { long int i = longval (); if (i != ($2)) return 1; fprintf (f, "%ld", i); } else { unsigned long int i = ulongval (); if (i != ($2)) return 1; fprintf (f, "%lu", i); } /* Do not output a trailing newline, as this causes \r\n confusion on some platforms. */ return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : echo >>conftest.val; read $3 config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by lcdf-typetools $as_me 2.108, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am__api_version='1.15' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='lcdf-typetools' VERSION='2.108' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi ac_config_headers="$ac_config_headers autoconf.h" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 $as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } # Check whether --enable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then : enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval else USE_MAINTAINER_MODE=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 $as_echo "$USE_MAINTAINER_MODE" >&6; } if test $USE_MAINTAINER_MODE = yes; then MAINTAINER_MODE_TRUE= MAINTAINER_MODE_FALSE='#' else MAINTAINER_MODE_TRUE='#' MAINTAINER_MODE_FALSE= fi MAINT=$MAINTAINER_MODE_TRUE { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CXX" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CXX_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 $as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if ${ac_cv_prog_CXXCPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 $as_echo "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Check whether --enable-warnings was given. if test "${enable_warnings+set}" = set; then : enableval=$enable_warnings; if test "$enableval" = yes; then CFLAGS="$CFLAGS -W -Wall"; CXXFLAGS="$CXXFLAGS -W -Wall" fi fi # Check whether --enable-precondition-checking was given. if test "${enable_precondition_checking+set}" = set; then : enableval=$enable_precondition_checking; if test "$enableval" = yes; then $as_echo "#define HAVE_PRECONDITION_CHECKING 1" >>confdefs.h fi fi # Check whether --enable-adobe-code was given. if test "${enable_adobe_code+set}" = set; then : enableval=$enable_adobe_code; else enable_adobe_code=yes fi if test "$enable_adobe_code" = yes; then $as_echo "#define HAVE_ADOBE_CODE 1" >>confdefs.h fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking where template objects are stored" >&5 $as_echo_n "checking where template objects are stored... " >&6; } if ${ac_cv_cxx_templobjs+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_cxx_templobjs='unknown' if test "$GXX" = yes; then ac_cv_cxx_templobjs='nowhere' else case $CXX in CC|*/CC) cat > conftest.cc < class A { public : A () {} }; template void f (const A&) {} main() { A d; A i; f (d); f (i); return 0; } EOF if test "$ac_cv_cxx_templobjs" = 'unknown' ; then if test -d Templates.DB ; then rm -fr Templates.DB fi if $CXX $CXXFLAGS -ptr. -c conftest.cc 1> /dev/null 2>&1; then if test -d Templates.DB ; then # this should be Sun CC <= 4.2 CXXFLAGS="$CXXFLAGS -ptr." if test x"$LIBTOOL" = x ; then ac_cv_cxx_templobjs='Templates.DB/*.o' else ac_cv_cxx_templobjs='Templates.DB/*.lo' fi rm -fr Templates.DB fi fi fi if test "$ac_cv_cxx_templobjs" = 'unknown' ; then if test -d SunWS_cache ; then rm -fr SunWS_cache fi if $CXX $CXXFLAGS -c conftest.cc 1> /dev/null 2>&1; then if test -d SunWS_cache ; then # this should be Sun WorkShop C++ compiler 5.x # or Sun Forte C++ compiler >= 6.x if test x"$LIBTOOL" = x ; then ac_cv_cxx_templobjs='SunWS_cache/*/*.o' else ac_cv_cxx_templobjs='SunWS_cache/*/*.lo' fi rm -fr SunWS_cache fi fi fi rm -f conftest* ;; esac fi case "x$ac_cv_cxx_templobjs" in xunknown|xnowhere) TEMPLATE_OBJS="" ;; *) TEMPLATE_OBJS="$ac_cv_cxx_templobjs" ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_templobjs" >&5 $as_echo "$ac_cv_cxx_templobjs" >&6; } ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi ac_header_dirent=no for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 $as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } if eval \${$as_ac_Header+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include <$ac_hdr> int main () { if ((DIR *) 0) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$as_ac_Header=yes" else eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$as_ac_Header { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 _ACEOF ac_header_dirent=$ac_hdr; break fi done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 $as_echo_n "checking for library containing opendir... " >&6; } if ${ac_cv_search_opendir+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char opendir (); int main () { return opendir (); ; return 0; } _ACEOF for ac_lib in '' dir; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_opendir=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_opendir+:} false; then : break fi done if ${ac_cv_search_opendir+:} false; then : else ac_cv_search_opendir=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 $as_echo "$ac_cv_search_opendir" >&6; } ac_res=$ac_cv_search_opendir if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 $as_echo_n "checking for library containing opendir... " >&6; } if ${ac_cv_search_opendir+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char opendir (); int main () { return opendir (); ; return 0; } _ACEOF for ac_lib in '' x; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_opendir=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_opendir+:} false; then : break fi done if ${ac_cv_search_opendir+:} false; then : else ac_cv_search_opendir=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 $as_echo "$ac_cv_search_opendir" >&6; } ac_res=$ac_cv_search_opendir if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in fcntl.h unistd.h sys/time.h sys/wait.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether works" >&5 $as_echo_n "checking whether works... " >&6; } if ${ac_cv_good_new_hdr+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int a; int *b = new(&a) int; return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_good_new_hdr=yes else ac_cv_good_new_hdr=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_good_new_hdr" >&5 $as_echo "$ac_cv_good_new_hdr" >&6; } if test "$ac_cv_good_new_hdr" = yes; then $as_echo "#define HAVE_NEW_HDR 1" >>confdefs.h fi for ac_header in new.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "new.h" "ac_cv_header_new_h" "$ac_includes_default" if test "x$ac_cv_header_new_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_NEW_H 1 _ACEOF fi done $as_echo "#define WORDS_BIGENDIAN_SET 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 $as_echo_n "checking whether byte ordering is bigendian... " >&6; } if ${ac_cv_c_bigendian+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_bigendian=unknown # See if we're dealing with a universal compiler. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __APPLE_CC__ not a universal capable compiler #endif typedef int dummy; _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : # Check for potential -arch flags. It is not universal unless # there are at least two -arch flags with different values. ac_arch= ac_prev= for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do if test -n "$ac_prev"; then case $ac_word in i?86 | x86_64 | ppc | ppc64) if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then ac_arch=$ac_word else ac_cv_c_bigendian=universal break fi ;; esac ac_prev= elif test "x$ac_word" = "x-arch"; then ac_prev=arch fi done fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_c_bigendian = unknown; then # See if sys/param.h defines the BYTE_ORDER macro. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ && LITTLE_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : # It does; now see whether it defined to BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : # It does; now see whether it defined to _BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #ifndef _BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # Compile a test program. if test "$cross_compiling" = yes; then : # Try to guess by grepping values from an object file. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; int use_ascii (int i) { return ascii_mm[i] + ascii_ii[i]; } short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; int use_ebcdic (int i) { return ebcdic_mm[i] + ebcdic_ii[i]; } extern int foo; int main () { return use_ascii (foo) == use_ebcdic (foo); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { /* Are we little or big endian? From Harbison&Steele. */ union { long int l; char c[sizeof (long int)]; } u; u.l = 1; return u.c[sizeof (long int) - 1] == 1; ; return 0; } _ACEOF if ac_fn_cxx_try_run "$LINENO"; then : ac_cv_c_bigendian=no else ac_cv_c_bigendian=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 $as_echo "$ac_cv_c_bigendian" >&6; } case $ac_cv_c_bigendian in #( yes) $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h ;; #( no) ;; #( universal) $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h ;; #( *) as_fn_error $? "unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu need_fixlibc=0 for ac_func in strerror do : ac_fn_c_check_func "$LINENO" "strerror" "ac_cv_func_strerror" if test "x$ac_cv_func_strerror" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRERROR 1 _ACEOF else need_fixlibc=1 fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for broken strtod" >&5 $as_echo_n "checking for broken strtod... " >&6; } if ${ac_cv_broken_strtod+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_broken_strtod=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main(int c, char **v) { char s[] = "12 "; char *endp; double d = strtod(s, &endp); return (s + 2) == endp; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_broken_strtod=yes else ac_cv_broken_strtod=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_broken_strtod" >&5 $as_echo "$ac_cv_broken_strtod" >&6; } if test "x$ac_cv_broken_strtod" = xyes; then need_fixlibc=1 $as_echo "#define HAVE_BROKEN_STRTOD 1" >>confdefs.h fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_fn_cxx_check_decl "$LINENO" "strnlen" "ac_cv_have_decl_strnlen" "#include " if test "x$ac_cv_have_decl_strnlen" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRNLEN $ac_have_decl _ACEOF for ac_func in strnlen do : ac_fn_cxx_check_func "$LINENO" "strnlen" "ac_cv_func_strnlen" if test "x$ac_cv_func_strnlen" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRNLEN 1 _ACEOF have_strnlen=1 else need_fixlibc=1 fi done if test "x$have_strnlen" = x1; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for broken strnlen" >&5 $as_echo_n "checking for broken strnlen... " >&6; } if ${ac_cv_broken_strnlen+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_broken_strnlen=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main(int c, char **v) { char s[] = "01234567891"; return strnlen(s, 10) == 10; } _ACEOF if ac_fn_cxx_try_run "$LINENO"; then : ac_cv_broken_strnlen=yes else ac_cv_broken_strnlen=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_broken_strnlen" >&5 $as_echo "$ac_cv_broken_strnlen" >&6; } if test "x$ac_cv_broken_strnlen" = xyes; then need_fixlibc=1 $as_echo "#define HAVE_BROKEN_STRNLEN 1" >>confdefs.h fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu for ac_func in ctime ftruncate mkstemp sigaction strdup strtoul vsnprintf waitpid do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_func "$LINENO" "floor" "ac_cv_func_floor" if test "x$ac_cv_func_floor" = xyes; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for floor in -lm" >&5 $as_echo_n "checking for floor in -lm... " >&6; } if ${ac_cv_lib_m_floor+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char floor (); int main () { return floor (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_floor=yes else ac_cv_lib_m_floor=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_floor" >&5 $as_echo "$ac_cv_lib_m_floor" >&6; } if test "x$ac_cv_lib_m_floor" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi fi ac_fn_c_check_func "$LINENO" "fabs" "ac_cv_func_fabs" if test "x$ac_cv_func_fabs" = xyes; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fabs in -lm" >&5 $as_echo_n "checking for fabs in -lm... " >&6; } if ${ac_cv_lib_m_fabs+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char fabs (); int main () { return fabs (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_fabs=yes else ac_cv_lib_m_fabs=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_fabs" >&5 $as_echo "$ac_cv_lib_m_fabs" >&6; } if test "x$ac_cv_lib_m_fabs" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi fi if test x$need_fixlibc = x1; then FIXLIBC_TRUE= FIXLIBC_FALSE='#' else FIXLIBC_TRUE='#' FIXLIBC_FALSE= fi for ac_header in inttypes.h do : ac_fn_c_check_header_mongrel "$LINENO" "inttypes.h" "ac_cv_header_inttypes_h" "$ac_includes_default" if test "x$ac_cv_header_inttypes_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_INTTYPES_H 1 _ACEOF have_inttypes_h=yes else have_inttypes_h=no fi done for ac_header in sys/types.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/types.h" "ac_cv_header_sys_types_h" "$ac_includes_default" if test "x$ac_cv_header_sys_types_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_TYPES_H 1 _ACEOF have_sys_types_h=yes else have_sys_types_h=no fi done if test $have_inttypes_h = no -a $have_sys_types_h = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uintXX_t typedefs" >&5 $as_echo_n "checking for uintXX_t typedefs... " >&6; } if ${ac_cv_uint_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "(^|[^a-zA-Z_0-9])uint32_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then : ac_cv_uint_t=yes else ac_cv_uint_t=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_uint_t" >&5 $as_echo "$ac_cv_uint_t" >&6; } fi if test $have_inttypes_h = no -a $have_sys_types_h = yes -a "$ac_cv_uint_t" = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for u_intXX_t typedefs" >&5 $as_echo_n "checking for u_intXX_t typedefs... " >&6; } if ${ac_cv_u_int_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "(^|[^a-zA-Z_0-9])u_int32_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then : ac_cv_u_int_t=yes else ac_cv_u_int_t=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_u_int_t" >&5 $as_echo "$ac_cv_u_int_t" >&6; } fi if test $have_inttypes_h = yes -o "$ac_cv_uint_t" = yes; then : elif test "$ac_cv_u_int_t" = yes; then $as_echo "#define HAVE_U_INT_TYPES 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ========================================= Neither uint32_t nor u_int32_t defined by or ! Assuming \"short\" has 16 bits and \"int\" has 32 bits. =========================================" >&5 $as_echo "$as_me: WARNING: ========================================= Neither uint32_t nor u_int32_t defined by or ! Assuming \"short\" has 16 bits and \"int\" has 32 bits. =========================================" >&2;} $as_echo "#define HAVE_FAKE_INT_TYPES 1" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "#if HAVE_INTTYPES_H # include #endif #if HAVE_SYS_TYPES_H # include #endif " if test "x$ac_cv_type_uintptr_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UINTPTR_T 1 _ACEOF fi # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5 $as_echo_n "checking size of void *... " >&6; } if ${ac_cv_sizeof_void_p+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default"; then : else if test "$ac_cv_type_void_p" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (void *) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_void_p=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5 $as_echo "$ac_cv_sizeof_void_p" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_VOID_P $ac_cv_sizeof_void_p _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long" >&5 $as_echo_n "checking size of unsigned long... " >&6; } if ${ac_cv_sizeof_unsigned_long+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long))" "ac_cv_sizeof_unsigned_long" "$ac_includes_default"; then : else if test "$ac_cv_type_unsigned_long" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (unsigned long) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_unsigned_long=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long" >&5 $as_echo "$ac_cv_sizeof_unsigned_long" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned int" >&5 $as_echo_n "checking size of unsigned int... " >&6; } if ${ac_cv_sizeof_unsigned_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned int))" "ac_cv_sizeof_unsigned_int" "$ac_includes_default"; then : else if test "$ac_cv_type_unsigned_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (unsigned int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_unsigned_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_int" >&5 $as_echo "$ac_cv_sizeof_unsigned_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_UNSIGNED_INT $ac_cv_sizeof_unsigned_int _ACEOF ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu for ac_header in byteorder.h netinet/in.h sys/param.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ntohs and ntohl are defined" >&5 $as_echo_n "checking whether ntohs and ntohl are defined... " >&6; } ac_ntoh_defined=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if HAVE_SYS_TYPES_H # include #endif #if HAVE_BYTEORDER_H # include #elif HAVE_NETINET_IN_H # include #elif HAVE_SYS_PARAM_H # include #endif #ifdef WIN32 # ifdef __MSC_VER # pragma warning (disable: 4290) # endif # include #endif int main () { (void) ntohs(0x0020), (void) ntohl(0x03040020); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ac_ntoh_defined=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_ntoh_defined = no; then for ac_header in arpa/inet.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "arpa/inet.h" "ac_cv_header_arpa_inet_h" "$ac_includes_default" if test "x$ac_cv_header_arpa_inet_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ARPA_INET_H 1 _ACEOF have_arpa_inet_h=yes else have_arpa_inet_h=no fi done if test $have_arpa_inet_h = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ntohs and ntohl are defined in " >&5 $as_echo_n "checking whether ntohs and ntohl are defined in ... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if HAVE_SYS_TYPES_H # include #endif #include int main () { (void) ntohs(0x0020), (void) ntohl(0x03040020); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define NEED_ARPA_INET_H 1" >>confdefs.h ac_ntoh_defined=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi fi if test $ac_ntoh_defined = no; then as_fn_error $? " ========================================= Cannot find a definition for ntohs and/or ntohl! =========================================" "$LINENO" 5 fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing ntohs" >&5 $as_echo_n "checking for library containing ntohs... " >&6; } if ${ac_cv_search_ntohs+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char ntohs (); int main () { return ntohs (); ; return 0; } _ACEOF for ac_lib in '' -lnet -lwinsock32; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_ntohs=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_ntohs+:} false; then : break fi done if ${ac_cv_search_ntohs+:} false; then : else ac_cv_search_ntohs=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ntohs" >&5 $as_echo "$ac_cv_search_ntohs" >&6; } ac_res=$ac_cv_search_ntohs if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for addressable va_list type" >&5 $as_echo_n "checking for addressable va_list type... " >&6; } if ${ac_cv_va_list_addr+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include void f(va_list *) { } void g(va_list val) { f(&val); } void h(int a, ...) { va_list val; va_start(val, a); g(val); va_end(val); } int main () { h(2, 3, 4); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_va_list_addr=yes else ac_cv_va_list_addr=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_va_list_addr" >&5 $as_echo "$ac_cv_va_list_addr" >&6; } if test "x$ac_cv_va_list_addr" = xyes; then $as_echo "#define HAVE_ADDRESSABLE_VA_LIST 1" >>confdefs.h fi ## Define configure options for lcdf-typetools. Extracted from configure.ac ## for ease of building TeX Live. # Check whether --enable-cfftot1 was given. if test "${enable_cfftot1+set}" = set; then : enableval=$enable_cfftot1; fi # Check whether --enable-mmafm was given. if test "${enable_mmafm+set}" = set; then : enableval=$enable_mmafm; fi # Check whether --enable-mmpfb was given. if test "${enable_mmpfb+set}" = set; then : enableval=$enable_mmpfb; fi # Check whether --enable-otfinfo was given. if test "${enable_otfinfo+set}" = set; then : enableval=$enable_otfinfo; fi # Check whether --enable-otftotfm was given. if test "${enable_otftotfm+set}" = set; then : enableval=$enable_otftotfm; fi # Check whether --enable-t1dotlessj was given. if test "${enable_t1dotlessj+set}" = set; then : enableval=$enable_t1dotlessj; fi # Check whether --enable-t1lint was given. if test "${enable_t1lint+set}" = set; then : enableval=$enable_t1lint; fi # Check whether --enable-t1rawafm was given. if test "${enable_t1rawafm+set}" = set; then : enableval=$enable_t1rawafm; fi # Check whether --enable-t1reencode was given. if test "${enable_t1reencode+set}" = set; then : enableval=$enable_t1reencode; fi # Check whether --enable-t1testpage was given. if test "${enable_t1testpage+set}" = set; then : enableval=$enable_t1testpage; fi # Check whether --enable-ttftotype42 was given. if test "${enable_ttftotype42+set}" = set; then : enableval=$enable_ttftotype42; fi # Check whether --enable-cfftot1 was given. if test "${enable_cfftot1+set}" = set; then : enableval=$enable_cfftot1; fi # Check whether --enable-t1dotlessj was given. if test "${enable_t1dotlessj+set}" = set; then : enableval=$enable_t1dotlessj; fi # Check whether --enable-ttftotype42 was given. if test "${enable_ttftotype42+set}" = set; then : enableval=$enable_ttftotype42; fi # Check whether --enable-updmap was given. if test "${enable_updmap+set}" = set; then : enableval=$enable_updmap; fi SELECTED_SUBDIRS= test "x$enable_cfftot1" = xno || SELECTED_SUBDIRS="$SELECTED_SUBDIRS cfftot1" test "x$enable_mmafm" = xno || SELECTED_SUBDIRS="$SELECTED_SUBDIRS mmafm" test "x$enable_mmpfb" = xno || SELECTED_SUBDIRS="$SELECTED_SUBDIRS mmpfb" test "x$enable_otfinfo" = xno || SELECTED_SUBDIRS="$SELECTED_SUBDIRS otfinfo" test "x$enable_otftotfm" = xno || SELECTED_SUBDIRS="$SELECTED_SUBDIRS otftotfm" test "x$enable_t1dotlessj" = xno || SELECTED_SUBDIRS="$SELECTED_SUBDIRS t1dotlessj" test "x$enable_t1lint" = xno || SELECTED_SUBDIRS="$SELECTED_SUBDIRS t1lint" test "x$enable_t1rawafm" = xno || SELECTED_SUBDIRS="$SELECTED_SUBDIRS t1rawafm" test "x$enable_t1reencode" = xno || SELECTED_SUBDIRS="$SELECTED_SUBDIRS t1reencode" test "x$enable_t1testpage" = xno || SELECTED_SUBDIRS="$SELECTED_SUBDIRS t1testpage" test "x$enable_ttftotype42" = xno || SELECTED_SUBDIRS="$SELECTED_SUBDIRS ttftotype42" if test "x$enable_auto_cfftot1" != xno; then : $as_echo "#define HAVE_AUTO_CFFTOT1 1" >>confdefs.h fi if test "x$enable_auto_t1dotlessj" != xno; then : $as_echo "#define HAVE_AUTO_T1DOTLESSJ 1" >>confdefs.h fi if test "x$enable_auto_ttftotype42" != xno; then : $as_echo "#define HAVE_AUTO_TTFTOTYPE42 1" >>confdefs.h fi if test "x$enable_auto_updmap" != xno; then : $as_echo "#define HAVE_AUTO_UPDMAP 1" >>confdefs.h fi # Check whether --with-kpathsea was given. if test "${with_kpathsea+set}" = set; then : withval=$with_kpathsea; kpathsea=$withval else kpathsea= fi KPATHSEA_INCLUDES= KPATHSEA_LIBS= KPATHSEA_DEPEND= if test "x$kpathsea" != xno; then SAVE_CPPFLAGS="$CPPFLAGS"; SAVE_LDFLAGS="$LDFLAGS" if test "x$kpathsea" != x -a "x$kpathsea" != xyes; then KPATHSEA_INCLUDES="-I$kpathsea/include" KPATHSEA_LIBS="-L$kpathsea/lib" else kpathsea=yes fi if true; then CPPFLAGS="$SAVE_CPPFLAGS $KPATHSEA_INCLUDES" ac_fn_cxx_check_header_mongrel "$LINENO" "kpathsea/kpathsea.h" "ac_cv_header_kpathsea_kpathsea_h" "$ac_includes_default" if test "x$ac_cv_header_kpathsea_kpathsea_h" = xyes; then : kpse_header=yes else kpse_header=no fi fi if test "x$kpse_header" != xyes -a "x$kpathsea" = xyes -a -r /usr/local/include/kpathsea/tex-file.h; then KPATHSEA_INCLUDES="-I/usr/local/include" KPATHSEA_LIBS="-L/usr/local/lib" CPPFLAGS="$SAVE_CPPFLAGS $KPATHSEA_INCLUDES" ac_fn_cxx_check_header_mongrel "$LINENO" "kpathsea/tex-file.h" "ac_cv_header_kpathsea_tex_file_h" "$ac_includes_default" if test "x$ac_cv_header_kpathsea_tex_file_h" = xyes; then : kpse_header=yes else kpse_header=no fi fi if true; then LDFLAGS="$SAVE_LDFLAGS $KPATHSEA_LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for kpse_set_program_name in -lkpathsea" >&5 $as_echo_n "checking for kpse_set_program_name in -lkpathsea... " >&6; } if ${ac_cv_lib_kpathsea_kpse_set_program_name+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lkpathsea $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char kpse_set_program_name (); int main () { return kpse_set_program_name (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_kpathsea_kpse_set_program_name=yes else ac_cv_lib_kpathsea_kpse_set_program_name=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_kpathsea_kpse_set_program_name" >&5 $as_echo "$ac_cv_lib_kpathsea_kpse_set_program_name" >&6; } if test "x$ac_cv_lib_kpathsea_kpse_set_program_name" = xyes; then : kpse_library=yes else kpse_library=no fi fi if test "x$kpse_header" != xyes -o "x$kpse_library" != xyes; then as_fn_error $? " ========================================= I can't find the kpathsea library and/or header files. Tell me where to look using the --with-kpathsea=PREFIX option (header files should be under PREFIX/include/kpathsea, and library under PREFIX/lib), or disable support using --without-kpathsea. =========================================" "$LINENO" 5 fi $as_echo "#define HAVE_KPATHSEA 1" >>confdefs.h if true; then KPATHSEA_LIBS="$KPATHSEA_LIBS -lkpathsea" fi if false; then $as_echo "#define HAVE_DECL_KPSE_OPENTYPE_FORMAT 1" >>confdefs.h else ac_fn_cxx_check_decl "$LINENO" "kpse_opentype_format" "ac_cv_have_decl_kpse_opentype_format" "#include " if test "x$ac_cv_have_decl_kpse_opentype_format" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_KPSE_OPENTYPE_FORMAT $ac_have_decl _ACEOF fi ac_fn_cxx_check_decl "$LINENO" "kpse_enc_format" "ac_cv_have_decl_kpse_enc_format" "#include " if test "x$ac_cv_have_decl_kpse_enc_format" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_KPSE_ENC_FORMAT $ac_have_decl _ACEOF CPPFLAGS="$SAVE_CPPFLAGS"; LDFLAGS="$SAVE_LDFLAGS" fi if test "x$with_kpathsea" != xno; then have_kpathsea_TRUE= have_kpathsea_FALSE='#' else have_kpathsea_TRUE='#' have_kpathsea_FALSE= fi # Check whether --enable-selfauto-set was given. if test "${enable_selfauto_set+set}" = set; then : enableval=$enable_selfauto_set; else enable_selfauto_set=yes fi if test "x$enable_selfauto_set" = xyes -a "x$kpathsea" != xno; then kpsewhich='kpsewhich' test "x$kpathsea" != xyes -a -x "$kpathsea/bin/kpsewhich" && kpsewhich="$kpathsea/bin/kpsewhich" SELFAUTOLOC="`$kpsewhich --expand-var='$SELFAUTOLOC' 2>/dev/null`" SELFAUTODIR="`$kpsewhich --expand-var='$SELFAUTODIR' 2>/dev/null`" SELFAUTOPARENT="`$kpsewhich --expand-var='$SELFAUTOPARENT' 2>/dev/null`" SELFAUTOGRANDPARENT="`$kpsewhich --expand-var='$SELFAUTOGRANDPARENT' 2>/dev/null`" if test -z "$SELFAUTODIR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ========================================= Could not extract SELFAUTO variables from $kpsewhich. Either supply the correct PREFIX to --with-kpathsea, or supply --disable-selfauto-loc. =========================================" >&5 $as_echo "$as_me: WARNING: ========================================= Could not extract SELFAUTO variables from $kpsewhich. Either supply the correct PREFIX to --with-kpathsea, or supply --disable-selfauto-loc. =========================================" >&2;} fi cat >>confdefs.h <<_ACEOF #define SELFAUTOLOC "$SELFAUTOLOC" _ACEOF cat >>confdefs.h <<_ACEOF #define SELFAUTODIR "$SELFAUTODIR" _ACEOF cat >>confdefs.h <<_ACEOF #define SELFAUTOPARENT "$SELFAUTOPARENT" _ACEOF if test -n "$SELFAUTOGRANDPARENT" -a "$SELFAUTOGRANDPARENT" != '$SELFAUTOGRANDPARENT'; then cat >>confdefs.h <<_ACEOF #define SELFAUTOGRANDPARENT "$SELFAUTOGRANDPARENT" _ACEOF fi fi # Check whether --enable-glyphlistdir was given. if test "${enable_glyphlistdir+set}" = set; then : enableval=$enable_glyphlistdir; glyphlistdir="$enableval" else glyphlistdir=NONE fi # Check whether --enable-encdir was given. if test "${enable_encdir+set}" = set; then : enableval=$enable_encdir; encdir="$enableval" else encdir=NONE fi test "x$glyphlistdir" = xNONE -o "x$glyphlistdir" = xno \ -o "x$glyphlistdir" = x && glyphlistdir='${pkgdatadir}' test "x$encdir" = xNONE -o "x$encdir" = xno \ -o "x$encdir" = x && encdir='${pkgdatadir}' KPATHSEA_RULE= $as_echo "#define HAVE_PERMSTRING 1" >>confdefs.h $as_echo "#define MMAFM_RUN_MMPFB 1" >>confdefs.h shell_expand () { val=`eval echo '$'"$1"` while echo "x$val" | grep '\$' >/dev/null 2>&1; do val=`eval echo "$val"`; done val=`echo "$val" | sed 's,//*,/,g'` eval "$1='$val'" } test "x$prefix" = xNONE && prefix=$ac_default_prefix test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' pkgdatadir="${datadir}/$PACKAGE" gdir="$glyphlistdir" for i in data dataroot pkgdata g; do shell_expand ${i}dir; done cat >>confdefs.h <<_ACEOF #define GLYPHLISTDIR "$gdir" _ACEOF ac_config_files="$ac_config_files Makefile liblcdf/Makefile libefont/Makefile cfftot1/Makefile mmafm/Makefile mmpfb/Makefile otfinfo/Makefile otftotfm/Makefile t1dotlessj/Makefile t1lint/Makefile t1rawafm/Makefile t1reencode/Makefile t1testpage/Makefile ttftotype42/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${FIXLIBC_TRUE}" && test -z "${FIXLIBC_FALSE}"; then as_fn_error $? "conditional \"FIXLIBC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${have_kpathsea_TRUE}" && test -z "${have_kpathsea_FALSE}"; then as_fn_error $? "conditional \"have_kpathsea\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by lcdf-typetools $as_me 2.108, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ lcdf-typetools config.status 2.108 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "autoconf.h") CONFIG_HEADERS="$CONFIG_HEADERS autoconf.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "liblcdf/Makefile") CONFIG_FILES="$CONFIG_FILES liblcdf/Makefile" ;; "libefont/Makefile") CONFIG_FILES="$CONFIG_FILES libefont/Makefile" ;; "cfftot1/Makefile") CONFIG_FILES="$CONFIG_FILES cfftot1/Makefile" ;; "mmafm/Makefile") CONFIG_FILES="$CONFIG_FILES mmafm/Makefile" ;; "mmpfb/Makefile") CONFIG_FILES="$CONFIG_FILES mmpfb/Makefile" ;; "otfinfo/Makefile") CONFIG_FILES="$CONFIG_FILES otfinfo/Makefile" ;; "otftotfm/Makefile") CONFIG_FILES="$CONFIG_FILES otftotfm/Makefile" ;; "t1dotlessj/Makefile") CONFIG_FILES="$CONFIG_FILES t1dotlessj/Makefile" ;; "t1lint/Makefile") CONFIG_FILES="$CONFIG_FILES t1lint/Makefile" ;; "t1rawafm/Makefile") CONFIG_FILES="$CONFIG_FILES t1rawafm/Makefile" ;; "t1reencode/Makefile") CONFIG_FILES="$CONFIG_FILES t1reencode/Makefile" ;; "t1testpage/Makefile") CONFIG_FILES="$CONFIG_FILES t1testpage/Makefile" ;; "ttftotype42/Makefile") CONFIG_FILES="$CONFIG_FILES ttftotype42/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi lcdf-typetools-2.108/autoconf.h.in0000664000175000017500000001375712732752552014042 00000000000000/* autoconf.h.in. Generated from configure.ac by autoheader. */ /* Define if building universal (internal helper macro) */ #undef AC_APPLE_UNIVERSAL_BUILD /* Directory for glyphlist.txt files. */ #undef GLYPHLISTDIR /* Define if the va_list type is addressable. */ #undef HAVE_ADDRESSABLE_VA_LIST /* Define to incldue Adobe code in output fonts. */ #undef HAVE_ADOBE_CODE /* Define to 1 if you have the header file. */ #undef HAVE_ARPA_INET_H /* Define to run cfftot1 from otftotfm. */ #undef HAVE_AUTO_CFFTOT1 /* Define to run t1dotlessj from otftotfm. */ #undef HAVE_AUTO_T1DOTLESSJ /* Define to run ttftotype42 from otftotfm. */ #undef HAVE_AUTO_TTFTOTYPE42 /* Define to run updmap from otftotfm. */ #undef HAVE_AUTO_UPDMAP /* Define if strnlen is broken. */ #undef HAVE_BROKEN_STRNLEN /* Define if strtod is broken. */ #undef HAVE_BROKEN_STRTOD /* Define to 1 if you have the header file. */ #undef HAVE_BYTEORDER_H /* Define to 1 if you have the `ctime' function. */ #undef HAVE_CTIME /* Define to 1 if you have the declaration of `kpse_enc_format', and to 0 if you don't. */ #undef HAVE_DECL_KPSE_ENC_FORMAT /* Define to 1 if you have the declaration of `kpse_opentype_format', and to 0 if you don't. */ #undef HAVE_DECL_KPSE_OPENTYPE_FORMAT /* Define to 1 if you have the declaration of `strnlen', and to 0 if you don't. */ #undef HAVE_DECL_STRNLEN /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_DIRENT_H /* Define if intXX_t types are not available. */ #undef HAVE_FAKE_INT_TYPES /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if you have the `ftruncate' function. */ #undef HAVE_FTRUNCATE /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define if you want to use kpathsea. */ #undef HAVE_KPATHSEA /* Define to 1 if you have the `m' library (-lm). */ #undef HAVE_LIBM /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `mkstemp' function. */ #undef HAVE_MKSTEMP /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_NDIR_H /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IN_H /* Define to 1 if you have the header file. */ #undef HAVE_NEW_H /* Define if exists and works. */ #undef HAVE_NEW_HDR /* Define if PermStrings are available. */ #undef HAVE_PERMSTRING /* Define to include precondition checking assertions. */ #undef HAVE_PRECONDITION_CHECKING /* Define to 1 if you have the `sigaction' function. */ #undef HAVE_SIGACTION /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strdup' function. */ #undef HAVE_STRDUP /* Define to 1 if you have the `strerror' function. */ #undef HAVE_STRERROR /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strnlen' function. */ #undef HAVE_STRNLEN /* Define to 1 if you have the `strtoul' function. */ #undef HAVE_STRTOUL /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_SYS_DIR_H /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_SYS_NDIR_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PARAM_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_WAIT_H /* Define to 1 if the system has the type `uintptr_t'. */ #undef HAVE_UINTPTR_T /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define if you have u_intXX_t types but not uintXX_t types. */ #undef HAVE_U_INT_TYPES /* Define to 1 if you have the `vsnprintf' function. */ #undef HAVE_VSNPRINTF /* Define to 1 if you have the `waitpid' function. */ #undef HAVE_WAITPID /* Define to 0 if you don't want mmafm to run mmpfb when it needs to get an intermediate master conversion program. */ #undef MMAFM_RUN_MMPFB /* Define to 1 if you must include to get `ntohl'. */ #undef NEED_ARPA_INET_H /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* kpsewhich's $SELFAUTODIR variable */ #undef SELFAUTODIR /* kpsewhich's $SELFAUTOGRANDPARENT variable */ #undef SELFAUTOGRANDPARENT /* kpsewhich's $SELFAUTOLOC variable */ #undef SELFAUTOLOC /* kpsewhich's $SELFAUTOPARENT variable */ #undef SELFAUTOPARENT /* The size of `unsigned int', as computed by sizeof. */ #undef SIZEOF_UNSIGNED_INT /* The size of `unsigned long', as computed by sizeof. */ #undef SIZEOF_UNSIGNED_LONG /* The size of `void *', as computed by sizeof. */ #undef SIZEOF_VOID_P /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN # undef WORDS_BIGENDIAN # endif #endif /* Define if WORDS_BIGENDIAN has been set. */ #undef WORDS_BIGENDIAN_SET lcdf-typetools-2.108/compile0000755000175000017500000001624512732752553013016 00000000000000#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2012-10-14.11; # UTC # Copyright (C) 1999-2014 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: lcdf-typetools-2.108/7t.enc0000664000175000017500000000540212732752520012446 00000000000000% A version of the 7t/OT1 encoding, with useful UNICODING comments, % intended for use with otftotfm. % We do not remove kerns between digits and other characters; a user who wants % tabular digits should select the OpenType "tnum" feature. % We also do not remove kerns between space and other characters; space is our % boundary character. /LCDF7TEncoding [ %00 /Gamma /Delta /Theta /Lambda /Xi /Pi /Sigma /Upsilon /Phi /Psi /Omega /ff /fi /fl /ffi /ffl %10 /dotlessi /dotlessj /grave /acute /caron /breve /macron /ring /cedilla /germandbls /ae /oe /oslash /AE /OE /Oslash %20 /space /exclam /quotedblright /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash %30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /exclamdown /equal /questiondown /question %40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O %50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /quotedblleft /bracketright /circumflex /dotaccent %60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o %70 /p /q /r /s /t /u /v /w /x /y /z /endash /emdash /hungarumlaut /tilde /dieresis %80 /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef %90 /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef %A0 /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef %B0 /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef %C0 /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef %D0 /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef %E0 /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef %F0 /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % LIGKERN question quoteleft =: questiondown ; % LIGKERN exclam quoteleft =: exclamdown ; % LIGKERN hyphen hyphen =: endash ; endash hyphen =: emdash ; % LIGKERN quoteleft quoteleft =: quotedblleft ; % LIGKERN quoteright quoteright =: quotedblright ; % LIGKERN || = 32 ; % UNICODING Delta =: Deltagreek Delta ; Omega =: Omegagreek Omega ; % UNICODING ff =: ; fi =: ; fl =: ; ffi =: ; ffl =: ; ] def lcdf-typetools-2.108/m4/0000755000175000017500000000000013423377072012025 500000000000000lcdf-typetools-2.108/m4/lcdf-typetools.m40000664000175000017500000000172012732752520015156 00000000000000## Define configure options for lcdf-typetools. Extracted from configure.ac ## for ease of building TeX Live. m4_define_default([kpse_indent_26], [26])[]dnl m4_define([kpse_lcdf_typetools_progs], [cfftot1 mmafm mmpfb otfinfo otftotfm t1dotlessj t1lint t1rawafm t1reencode t1testpage ttftotype42])[]dnl AC_FOREACH([Kpse_Prog], kpse_lcdf_typetools_progs, [AC_ARG_ENABLE(Kpse_Prog, AS_HELP_STRING([--disable-]Kpse_Prog, [do not build the ]Kpse_Prog[ program], kpse_indent_26))]) m4_define([kpse_otftotfm_auto_opts], [cfftot1 t1dotlessj ttftotype42 updmap])[]dnl AC_FOREACH([Kpse_Opt], kpse_otftotfm_auto_opts, [AC_ARG_ENABLE(Kpse_Opt, AS_HELP_STRING([--disable-auto-]Kpse_Opt, [disable running ]Kpse_Opt[ from otftotfm], kpse_indent_26))]) lcdf-typetools-2.108/mmpfb/0000755000175000017500000000000013423377073012607 500000000000000lcdf-typetools-2.108/mmpfb/myfont.cc0000644000175000017500000002136613423375327014362 00000000000000/* myfont.cc -- general multiple- to single-master conversion * * Copyright (c) 1997-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include "myfont.hh" #include #include #include "t1rewrit.hh" #include #include #include #include #include #include using namespace Efont; MyFont::MyFont(Type1Reader &reader) : Type1Font(reader) { } MyFont::~MyFont() { } void MyFont::kill_def(Type1Definition *t1d, int whichd) { if (!t1d) return; if (whichd < 0) for (whichd = dFont; whichd < dLast; whichd = (Dict)(whichd + 1)) if (dict(whichd, t1d->name()) == t1d) break; if (whichd < 0 || whichd >= dLast || dict(whichd, t1d->name()) != t1d) return; int icount = nitems(); for (int i = first_dict_item(whichd); i < icount; i++) if (item(i) == t1d) { StringAccum sa; sa << '%'; t1d->gen(sa); PermString name = t1d->name(); Type1CopyItem *t1ci = new Type1CopyItem(sa.take_string()); set_item(i, t1ci); set_dict(whichd, name, 0); return; } assert(0); } bool MyFont::set_design_vector(MultipleMasterSpace *mmspace, const Vector &design, ErrorHandler *errh) { Type1Definition *t1d = dict("DesignVector"); if (t1d) { t1d->set_numvec(design); kill_def(t1d, dFont); } t1d = dict("NormDesignVector"); if (t1d) { NumVector norm_design; if (mmspace->design_to_norm_design(design, norm_design)) t1d->set_numvec(norm_design); kill_def(t1d, dFont); } if (!mmspace->design_to_weight(design, _weight_vector, errh)) return false; // Need to check for case when all design coordinates are unspecified. The // font file contains a default WeightVector, but possibly NOT a default // DesignVector; we don't want to generate a FontName like // `MyriadMM_-9.79797979e97_-9.79797979e97_' because the DesignVector // components are unknown. if (!KNOWN(design[0])) { errh->error("must specify %s%,s %s coordinate", font_name().c_str(), mmspace->axis_type(0).c_str()); return false; } t1d = dict("WeightVector"); if (t1d) { t1d->set_numvec(_weight_vector); kill_def(t1d, dFont); } int naxes = design.size(); _nmasters = _weight_vector.size(); PermString name; t1d = dict("FontName"); if (t1d && t1d->value_name(name)) { StringAccum sa(name); for (int a = 0; a < naxes; a++) sa << '_' << design[a]; // Multiple masters require an underscore AFTER the font name sa << '_'; t1d->set_name(sa.c_str()); uncache_defs(); // remove cached font name } // add a FullName too String full_name; t1d = fi_dict("FullName"); if (t1d && t1d->value_string(full_name)) { StringAccum sa(full_name); for (int a = 0; a < naxes; a++) { sa << (a ? ' ' : '_') << design[a]; PermString label = mmspace->axis_abbreviation(a); if (label) sa << ' ' << label; } t1d->set_string(sa.c_str()); } // save UniqueID, then kill its definition int uniqueid; t1d = dict("UniqueID"); bool have_uniqueid = (t1d && t1d->value_int(uniqueid)); kill_def(t1d, dFont); // prepare XUID t1d = dict("XUID"); NumVector xuid; if (!t1d || !t1d->value_numvec(xuid)) { if (have_uniqueid) { t1d = ensure(dFont, "XUID"); xuid.clear(); xuid.push_back(1); xuid.push_back(uniqueid); } else if (t1d) { kill_def(t1d, dFont); t1d = 0; } } if (t1d) { // Append design vector values to the XUID to prevent cache pollution. for (int a = 0; a < naxes; a++) xuid.push_back((int)(design[a] * 100)); t1d->set_numvec(xuid); } return true; } void MyFont::interpolate_dict_int(PermString name, Dict the_dict, ErrorHandler *errh) { Type1Definition *def = dict(the_dict, name); Type1Definition *blend_def = dict(the_dict + dBlend, name); NumVector blend; if (def && blend_def && blend_def->value_numvec(blend)) { int n = _nmasters; double val = 0; for (int m = 0; m < n; m++) val += blend[m] * _weight_vector[m]; int ival = (int)floor(val + 0.50001); if (fabs(val - ival) >= 0.001) errh->warning("interpolated %s should be an integer (it is %g)", name.c_str(), val); def->set_num(ival); kill_def(blend_def, the_dict + dBlend); } } void MyFont::interpolate_dict_num(PermString name, Dict the_dict, bool force_integer) { Type1Definition *def = dict(the_dict, name); Type1Definition *blend_def = dict(the_dict + dBlend, name); NumVector blend; if (def && blend_def && blend_def->value_numvec(blend)) { int n = _nmasters; double val = 0; for (int m = 0; m < n; m++) val += blend[m] * _weight_vector[m]; if (force_integer) val = floor(val + 0.50001); def->set_num(val); kill_def(blend_def, the_dict + dBlend); } else if (def && !blend_def && force_integer) { double val; if (def->value_num(val)) def->set_num(floor(val + 0.50001)); } } void MyFont::interpolate_dict_numvec(PermString name, Dict the_dict, int round_mode, bool executable) { Type1Definition *def = dict(the_dict, name); Type1Definition *blend_def = dict(the_dict + dBlend, name); Vector blend; if (def && blend_def && blend_def->value_numvec_vec(blend)) { int n = blend.size(); NumVector val; for (int i = 0; i < n; i++) { double d = 0; for (int m = 0; m < _nmasters; m++) d += blend[i][m] * _weight_vector[m]; if (round_mode == 2 && i < 2) d = floor(d - 0.50001); else if (round_mode) d = floor(d + 0.50001); val.push_back(d); } def->set_numvec(val, executable); kill_def(blend_def, the_dict + dBlend); } } void MyFont::interpolate_dicts(bool force_integer, ErrorHandler *errh) { // Unfortunately, some programs (acroread) expect the FontBBox to consist // of integers. Round its elements away from zero (this is what the // Acrobat distiller seems to do). interpolate_dict_numvec("FontBBox", dFont, 2, true); interpolate_dict_numvec("BlueValues", dPrivate, force_integer); interpolate_dict_numvec("OtherBlues", dPrivate, force_integer); interpolate_dict_numvec("FamilyBlues", dPrivate, force_integer); interpolate_dict_numvec("FamilyOtherBlues", dPrivate, force_integer); interpolate_dict_numvec("StdHW", dPrivate); interpolate_dict_numvec("StdVW", dPrivate); interpolate_dict_numvec("StemSnapH", dPrivate); interpolate_dict_numvec("StemSnapV", dPrivate); interpolate_dict_num("BlueScale", dPrivate); interpolate_dict_num("BlueShift", dPrivate, force_integer); interpolate_dict_int("BlueFuzz", dPrivate, errh); { Type1Definition *def = p_dict("ForceBold"); Type1Definition *blend_def = bp_dict("ForceBold"); Type1Definition *thresh = p_dict("ForceBoldThreshold"); Vector namevec; double thresh_val; if (def && blend_def && thresh && blend_def->value_namevec(namevec) && thresh->value_num(thresh_val) && namevec.size() == _nmasters) { double v = 0; for (int m = 0; m < _nmasters; m++) if (namevec[m] == "true") v += _weight_vector[m]; def->set_code(v >= thresh_val ? "true" : "false"); kill_def(blend_def, dBlendPrivate); } } interpolate_dict_num("UnderlinePosition", dFontInfo); interpolate_dict_num("UnderlineThickness", dFontInfo); interpolate_dict_num("ItalicAngle", dFontInfo); if (Type1Definition *def = bp_dict("BuildCharArray")) kill_def(def, dBlendPrivate); for (DictHashMap::const_iterator i = dict_begin(dBlend); i; i++) { PermString name = i.key(); if (i.value() && name != "Private" && name != "FontInfo" && name != "ConvertDesignVector" && name != "NormalizeDesignVector") errh->warning("didn%,t interpolate %s in Blend", name.c_str()); } for (DictHashMap::const_iterator i = dict_begin(dBlendPrivate); i; i++) if (i.value() && i.key() != "Erode") errh->warning("didn%,t interpolate %s in BlendPrivate", i.key().c_str()); kill_def(p_dict("NDV"), dPrivate); kill_def(p_dict("CDV"), dPrivate); kill_def(p_dict("UniqueID"), dPrivate); kill_def(fi_dict("BlendDesignPositions"), dFontInfo); kill_def(fi_dict("BlendDesignMap"), dFontInfo); kill_def(fi_dict("BlendAxisTypes"), dFontInfo); } void MyFont::interpolate_charstrings(int precision, ErrorHandler *errh) { Type1MMRemover remover(this, _weight_vector, precision, errh); remover.run(); } lcdf-typetools-2.108/mmpfb/t1rewrit.hh0000664000175000017500000000275012732752520014633 00000000000000#ifndef T1REWRIT_HH #define T1REWRIT_HH #include #include #include class Type1MMRemover { public: Type1MMRemover(Efont::Type1Font *, const Vector &weight_vec, int, ErrorHandler *); ~Type1MMRemover(); Efont::CharstringProgram *program() const { return _font; } const Vector &weight_vector() const { return _weight_vector; } int nmasters() const { return _weight_vector.size(); } int precision() const { return _precision; } Efont::Type1Charstring *subr_prefix(int); Efont::Type1Charstring *subr_expander(int); void run(); private: Efont::Type1Font *_font; Vector _weight_vector; int _precision; int _nsubrs; Vector _subr_done; Vector _subr_prefix; Vector _must_expand_subr; Vector _hint_replacement_subr; bool _expand_all_subrs; ErrorHandler *_errh; }; class Type1SubrRemover { public: Type1SubrRemover(Efont::Type1Font *, ErrorHandler *); ~Type1SubrRemover(); Efont::CharstringProgram *program() const { return _font; } ErrorHandler *errh() const { return _errh; } int save_count() const { return _save_count; } bool run(int); private: Efont::Type1Font *_font; int _nsubrs; enum { REMOVABLE = -1, DEAD = -2 }; Vector _renumbering; Vector _cost; int _save_count; int _nonexist_count; ErrorHandler *_errh; }; #endif lcdf-typetools-2.108/mmpfb/t1minimize.cc0000644000175000017500000000245513423375327015132 00000000000000/* t1minimize.cc -- make minimal copy of a Type 1 font * * Copyright (c) 2003-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include "t1minimize.hh" #include #include using namespace Efont; Type1Font * minimize(Type1Font *font) { Vector xuid_extension; xuid_extension.push_back(0x000395C1); Type1Font *output = Type1Font::skeleton_make_copy(font, font->font_name(), &xuid_extension); // Subrs for (int i = 0; i < font->nsubrs(); i++) if (Type1Subr *s = font->subr_x(i)) output->set_subr(s->subrno(), s->t1cs(), s->definer()); // CharStrings for (int i = 0; i < font->nglyphs(); i++) if (Type1Subr *g = font->glyph_x(i)) output->add_glyph(Type1Subr::make_glyph(g->name(), g->t1cs(), g->definer())); return output; } lcdf-typetools-2.108/mmpfb/main.cc0000644000175000017500000002745213423375327013774 00000000000000/* main.cc -- driver for mmpfb program * * Copyright (c) 1997-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include "myfont.hh" #include "t1rewrit.hh" #include "t1minimize.hh" #include #include #include #include #include #include #include #include #ifdef HAVE_CTIME # include #endif #if defined(_MSDOS) || defined(_WIN32) # include # include #endif #define WEIGHT_OPT 300 #define WIDTH_OPT 301 #define OPSIZE_OPT 302 #define STYLE_OPT 303 #define N1_OPT 304 #define N2_OPT 305 #define N3_OPT 306 #define N4_OPT 307 #define VERSION_OPT 308 #define AMCP_INFO_OPT 309 #define HELP_OPT 310 #define PFA_OPT 311 #define PFB_OPT 312 #define OUTPUT_OPT 313 #define QUIET_OPT 314 #define PRECISION_OPT 315 #define SUBRS_OPT 316 #define MINIMIZE_OPT 317 const Clp_Option options[] = { { "1", '1', N1_OPT, Clp_ValDouble, 0 }, { "2", '2', N2_OPT, Clp_ValDouble, 0 }, { "3", '3', N3_OPT, Clp_ValDouble, 0 }, { "4", '4', N4_OPT, Clp_ValDouble, 0 }, { "amcp-info", 0, AMCP_INFO_OPT, 0, 0 }, { "help", 'h', HELP_OPT, 0, 0 }, { "minimize", 'm', MINIMIZE_OPT, 0, Clp_Negate }, { "optical-size", 'O', OPSIZE_OPT, Clp_ValDouble, 0 }, { "output", 'o', OUTPUT_OPT, Clp_ValString, 0 }, { "pfa", 'a', PFA_OPT, 0, 0 }, { "pfb", 'b', PFB_OPT, 0, 0 }, { "precision", 'p', PRECISION_OPT, Clp_ValUnsigned, 0 }, { "quiet", 'q', QUIET_OPT, 0, Clp_Negate }, { "style", 0, STYLE_OPT, Clp_ValDouble, 0 }, { "subrs", 0, SUBRS_OPT, Clp_ValInt, Clp_Negate }, { "version", 'v', VERSION_OPT, 0, 0 }, { "wd", 0, WIDTH_OPT, Clp_ValDouble, 0 }, { "weight", 'w', WEIGHT_OPT, Clp_ValDouble, 0 }, { "width", 'W', WIDTH_OPT, Clp_ValDouble, 0 }, { "wt", 0, WEIGHT_OPT, Clp_ValDouble, 0 }, }; using namespace Efont; static const char *program_name; static ErrorHandler *errh; static MyFont *font; static MultipleMasterSpace *mmspace; static Vector ax_names; static Vector ax_nums; static Vector values; void usage_error(const char *error_message, ...) { va_list val; va_start(val, error_message); if (!error_message) errh->message("Usage: %s [OPTION]... FONT", program_name); else errh->xmessage(ErrorHandler::e_error, error_message, val); errh->message("Type %s --help for more information.", program_name); exit(1); } void usage() { FileErrorHandler uerrh(stdout); uerrh.message("\ % creates a single-master PostScript Type 1 font by interpolating a\n\ multiple master font at a point you specify. The resulting font does not\n\ contain multiple master extensions. It is written to the standard output.\n\ \n\ Usage: %s [OPTION]... FONT\n\ \n\ FONT is either the name of a PFA or PFB multiple master font file, or a\n\ PostScript font name. In the second case, mmpfb will find the actual outline\n\ file using the PSRESOURCEPATH environment variable.\n\ \n\ General options:\n\ --amcp-info Print AMCP info, if necessary, and exit.\n\ -a, --pfa Output PFA font.\n\ -b, --pfb Output PFB font. This is the default.\n\ -o, --output=FILE Write output to FILE.\n\ -p, --precision=N Set precision to N (larger means more precise).\n\ --subrs=N Limit output font to at most N subroutines.\n\ --no-minimize Do not replace original font%,s PostScript code.\n\ -h, --help Print this message and exit.\n\ -q, --quiet Do not generate any error messages.\n\ -v, --version Print version number and exit.\n\ \n\ Interpolation settings:\n\ -w, --weight=N Set weight to N.\n\ -W, --width=N Set width to N.\n\ -O, --optical-size=N Set optical size to N.\n\ --style=N Set style axis to N.\n\ --1=N, --2=N, --3=N, --4=N Set first (second, third, fourth) axis to N.\n\ \n\ Report bugs to .\n", program_name); } static void set_design(PermString a, double v) { ax_names.push_back(a); ax_nums.push_back(-1); values.push_back(v); } static void set_design(int a, double v) { ax_names.push_back(PermString()); ax_nums.push_back(a); values.push_back(v); } void do_file(const char *filename, PsresDatabase *psres) { FILE *f; if (strcmp(filename, "-") == 0) { f = stdin; filename = ""; #if defined(_MSDOS) || defined(_WIN32) _setmode(_fileno(f), _O_BINARY); #endif } else f = fopen(filename, "rb"); if (!f) { // check for PostScript or instance name Filename fn = psres->filename_value("FontOutline", filename); const char *underscore = strchr(filename, '_'); if (!fn && underscore) { fn = psres->filename_value ("FontOutline", PermString(filename, underscore - filename)); int i = 0; while (underscore[0] == '_' && underscore[1]) { double x = strtod(underscore + 1, const_cast(&underscore)); set_design(i, x); i++; } } f = fn.open_read(); } if (!f) errh->fatal("%s: %s", filename, strerror(errno)); Type1Reader *reader; int c = getc(f); ungetc(c, f); if (c == EOF) errh->fatal("%s: empty file", filename); if (c == 128) reader = new Type1PFBReader(f); else reader = new Type1PFAReader(f); font = new MyFont(*reader); delete reader; if (!font->ok()) errh->fatal("%s: invalid font", filename); else if (font->nglyphs() == 0) errh->fatal("%s: font contains no characters", filename); mmspace = font->create_mmspace(errh); if (!mmspace) errh->fatal("%s: not a multiple master font", filename); font->undo_synthetic(); } static void print_conversion_program(FILE *f, const Type1Charstring &cs, PermString name) { if (cs) { const unsigned char *data = cs.data(); for (int i = 0; i < cs.length(); ) { int l = cs.length() - i; if (l > 32) l = 32; fprintf(f, "%s <", name.c_str()); for (int j = 0; j < l; j++) fprintf(f, "%02X", data[j]); fprintf(f, ">\n"); data += l; i += l; } } } static void print_amcp_info(MultipleMasterSpace *mmspace, FILE *f) { const Type1Charstring &ndv = mmspace->ndv(); const Type1Charstring &cdv = mmspace->cdv(); if (!ndv && !cdv) fprintf(stderr, "%s does not have conversion programs.\n", mmspace->font_name().c_str()); else { fprintf(f, "StartConversionPrograms %d %d\n", ndv.length(), cdv.length()); print_conversion_program(f, ndv, "NDV"); print_conversion_program(f, cdv, "CDV"); fprintf(f, "EndConversionPrograms\n"); } } int main(int argc, char *argv[]) { PsresDatabase *psres = new PsresDatabase; psres->add_psres_path(getenv("PSRESOURCEPATH"), 0, false); Clp_Parser *clp = Clp_NewParser(argc, (const char * const *)argv, sizeof(options) / sizeof(options[0]), options); program_name = Clp_ProgramName(clp); bool write_pfb = true; bool amcp_info = false; bool minimize = true; int precision = 5; int subr_count = -1; FILE *outfile = 0; ::errh = ErrorHandler::static_initialize(new FileErrorHandler(stderr, String(program_name) + ": ")); while (1) { int opt = Clp_Next(clp); switch (opt) { case WEIGHT_OPT: set_design("Weight", clp->val.d); break; case WIDTH_OPT: set_design("Width", clp->val.d); break; case OPSIZE_OPT: set_design("OpticalSize", clp->val.d); break; case STYLE_OPT: set_design("Style", clp->val.d); break; case N1_OPT: case N2_OPT: case N3_OPT: case N4_OPT: set_design(opt - N1_OPT, clp->val.d); break; case AMCP_INFO_OPT: amcp_info = true; break; case PFA_OPT: write_pfb = false; break; case PFB_OPT: write_pfb = true; break; case PRECISION_OPT: if (clp->val.i > 107) { errh->warning("precision lowered to 107"); precision = 107; } else if (clp->val.i < 1) { errh->warning("precision raised to 1"); precision = 1; } else precision = clp->val.i; break; case SUBRS_OPT: if (clp->negated) subr_count = -1; else if (clp->val.i <= 0) errh->warning("subr count too small"); else subr_count = clp->val.i; break; case MINIMIZE_OPT: minimize = !clp->negated; break; case QUIET_OPT: if (clp->negated) errh = ErrorHandler::default_handler(); else errh = new SilentErrorHandler; break; case OUTPUT_OPT: if (outfile) errh->fatal("output file already specified"); if (strcmp(clp->vstr, "-") == 0) outfile = stdout; else { outfile = fopen(clp->vstr, "wb"); if (!outfile) errh->fatal("%s: %s", clp->vstr, strerror(errno)); } break; case VERSION_OPT: printf("mmpfb (LCDF typetools) %s\n", VERSION); printf("Copyright (C) 1997-2019 Eddie Kohler\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); exit(0); break; case HELP_OPT: usage(); exit(0); break; case Clp_NotOption: do_file(clp->vstr, psres); break; case Clp_Done: if (!font) usage_error("missing font argument"); goto done; case Clp_BadOption: usage_error(0); break; default: break; } } done: if (outfile == 0) outfile = stdout; if (amcp_info) { print_amcp_info(mmspace, outfile); exit(0); } Vector design = mmspace->empty_design_vector(); for (int i = 0; i < values.size(); i++) if (ax_names[i]) mmspace->set_design(design, ax_names[i], values[i], errh); else mmspace->set_design(design, ax_nums[i], values[i], errh); Vector default_design = mmspace->default_design_vector(); for (int i = 0; i < mmspace->naxes(); i++) if (!KNOWN(design[i]) && KNOWN(default_design[i])) { errh->warning("using default value %g for %s%,s %s", default_design[i], font->font_name().c_str(), mmspace->axis_type(i).c_str()); design[i] = default_design[i]; } if (!font->set_design_vector(mmspace, design, errh)) exit(1); font->interpolate_dicts(minimize, errh); font->interpolate_charstrings(precision, errh); if (subr_count >= 0) { Type1SubrRemover sr(font, errh); sr.run(subr_count); } font->fill_in_subrs(); Type1Font *t1font; if (minimize) { t1font = ::minimize(font); delete font; } else t1font = font; { // Add an identifying comment. #if HAVE_CTIME time_t cur_time = time(0); char *time_str = ctime(&cur_time); int time_len = strlen(time_str) - 1; char *buf = new char[strlen(VERSION) + time_len + 100]; sprintf(buf, "%%%% Interpolated by mmpfb-%s on %.*s.", VERSION, time_len, time_str); #else char *buf = new char[strlen(VERSION) + 100]; sprintf(buf, "%%%% Interpolated by mmpfb-%s.", VERSION); #endif t1font->add_header_comment(buf); t1font->add_header_comment("%% Mmpfb is free software. See ."); delete[] buf; } if (write_pfb) { #if defined(_MSDOS) || defined(_WIN32) _setmode(_fileno(outfile), _O_BINARY); #endif Type1PFBWriter w(outfile); t1font->write(w); } else { Type1PFAWriter w(outfile); t1font->write(w); } return 0; } lcdf-typetools-2.108/mmpfb/t1minimize.hh0000664000175000017500000000021412732752520015131 00000000000000#ifndef EFONT_T1MINIMIZE_HH #define EFONT_T1MINIMIZE_HH #include Efont::Type1Font *minimize(Efont::Type1Font *); #endif lcdf-typetools-2.108/mmpfb/mmpfb.10000644000175000017500000001116313423376706013716 00000000000000.\" -*-nroff-*- .ds V 2.108 .de M .BR "\\$1" "(\\$2)\\$3" .. .ds E " \-\- .if t .ds E \(em .de Op .BR "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" .. .de Oy .BI "\\$1\fR=" "\\$2\fR, " "\\$3\& " "\\$4" "\\$5" "\\$6" .. .de Ol .BI "\\$1\fR=" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" .. .de Sp .if n .sp .if t .sp 0.4 .. .TH MMPFB 1 "LCDF Typetools" "Version \*V" .SH NAME mmpfb \- creates single-master fonts from multiple master fonts ' .SH SYNOPSIS .B mmpfb \%[OPTIONS...] .I font ' .SH DESCRIPTION .B Mmpfb creates a normal, single-master PostScript font from a multiple master font by interpolation. You pass it a PFB or PFA font and options specifying the design point you want; it writes the resulting PFB or PFA font to the standard output. .PP The fonts .B mmpfb creates are interpolated at a low level to remove multiple master instructions from individual characters. Therefore, they can be used by programs that don't normally understand multiple master fonts, like .BR ps2pk (1). .PP .B Mmpfb supports fonts with intermediate masters, like Adobe Jenson and Kepler. It can also create AMCP (Adobe Multiple Master Conversion Program) files for use by .M mmafm 1 ; see .B \-\-amcp\-info below. .PP The .I font argument is either the name of a PFA or PFB font file, or a PostScript font name. If you give a font name, .B mmpfb will find the actual outline file using the PSRESOURCEPATH environment variable. This colon-separated path is searched for `PSres.upr' files, an Adobe method for indexing PostScript resources. .PP You can also give the name of a multiple master font instance, like `MinionMM_367_400_12_'. .B Mmpfb will parse the font name and create that instance for you. `PSres.upr' files must be set up for this to work. ' ' .SH EXAMPLE ' .nf % mmpfb \-\-weight=400 \-\-width=600 MyriadMM.pfb > MyriadMM_400_600_.pfb .fi ' .SH OPTIONS Long options may be abbreviated to their unique prefixes. ' .TP 5 .Oy \-\-output file \-o file ' Send output to .I file instead of standard output. ' .TP .BR \-\-pfb ", " \-b ' Output a PFB font. This is the default. ' .TP .BR \-\-pfa ", " \-a ' Output a PFA font. ' .TP .Op \-\-amcp\-info ' Do not create a font; instead, output an AMCP file for use by .M mmafm 1 . A message is printed if the font doesn't have intermediate masters, in which case no AMCP file is necessary. ' .TP .Oy \-\-weight N \-w N ' Set the weight axis to .IR N . ' .TP .Oy \-\-width N \-W N ' Set the width axis to .IR N . ' .TP .Oy \-\-optical\-size N \-O N ' Set the optical size axis to .IR N . ' .TP .Ol \-\-style N ' Set the style axis to .IR N . .TP \fB\-\-1\fR=\fIN\fR (\fB\-\-2\fR=\fIN\fR, \fB\-\-3\fR=\fIN\fR, \fB\-\-4\fR=\fIN\fR) ' Set the first (second, third, fourth) axis to .IR N . ' .TP .Oy \-\-precision N \-p N ' Set the output precision to .IR N . Higher values mean the control points in the output font will be more exactly aligned; lower values (1 or 2) create smaller output font files, and are close enough for most purposes. A precision of .IR N means that each point will be within .RI 1/ N font units of the exact interpolated value. (A font unit is generally 1/7200 inch for a 10-point font.) The default is 5. ' .TP .Ol \-\-subrs N ' Limit the output font to at most .IR N subroutines. 256 is a good value for .IR N . ' .TP .BR \-\-no\-minimize ' Do not minimize the output font definition. By default, .B mmpfb removes extra PostScript code and dictionary definitions from the font. Supply the .B \-\-no\-minimize option to avoid this behavior. ' .SH TROUBLESHOOTING .LP The "IBM" Type 1 font interpreter shipped as part of the X font server and .B ps2pk (among others) is inappropriately strict about PostScript code embedded in a font. The .B \-\-minimize option (now the default) fixes this problem. .LP Some versions of Adobe Acrobat Distiller may report "Warning: unable to embed font X. Invalid character outline data" when distilling an instance generated by .BR mmpfb . This is due to a limitation in the number of font subroutines Distiller can accept. (Multiple master fonts, and the single-master fonts generated by .BR mmpfb , tend to have a lot of subroutines.) Try limiting the number of subroutines in the generated font with the .Op \-\-subrs option. ' .SH SEE ALSO .M mmafm 1 ' .SH DIAGNOSTICS .TP 5 reducing \fIfont\fR to minimum number of subroutines (\fIN\fR) You tried to reduce the number of subroutines to less than \fIN\fR using the .Op \-\-subrs option, but the font needs at least \fIN\fR to function. The output font will have \fIN\fR subroutines. ' .SH AUTHOR .na Eddie Kohler, ekohler@gmail.com .PP The latest version is available from: .br http://www.lcdf.org/type/ .PP Thanks to Melissa O'Neill for suggestions and patient debugging. lcdf-typetools-2.108/mmpfb/Makefile.in0000644000175000017500000005236213423376574014611 00000000000000# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : bin_PROGRAMS = mmpfb$(EXEEXT) subdir = mmpfb ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/lcdf-typetools.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/autoconf.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" PROGRAMS = $(bin_PROGRAMS) am_mmpfb_OBJECTS = myfont.$(OBJEXT) main.$(OBJEXT) \ t1minimize.$(OBJEXT) t1rewrit.$(OBJEXT) mmpfb_OBJECTS = $(am_mmpfb_OBJECTS) mmpfb_DEPENDENCIES = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(mmpfb_SOURCES) DIST_SOURCES = $(mmpfb_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KPATHSEA_DEPEND = @KPATHSEA_DEPEND@ KPATHSEA_INCLUDES = @KPATHSEA_INCLUDES@ KPATHSEA_LIBS = @KPATHSEA_LIBS@ KPATHSEA_RULE = @KPATHSEA_RULE@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SELECTED_SUBDIRS = @SELECTED_SUBDIRS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TEMPLATE_OBJS = @TEMPLATE_OBJS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ encdir = @encdir@ exec_prefix = @exec_prefix@ glyphlistdir = @glyphlistdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign man_MANS = mmpfb.1 mmpfb_SOURCES = myfont.cc myfont.hh \ main.cc \ t1minimize.cc t1minimize.hh \ t1rewrit.cc t1rewrit.hh mmpfb_LDADD = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_CPPFLAGS = -I$(srcdir)/../include CLEANFILES = @TEMPLATE_OBJS@ EXTRA_DIST = mmpfb.1 all: all-am .SUFFIXES: .SUFFIXES: .cc .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign mmpfb/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign mmpfb/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) mmpfb$(EXEEXT): $(mmpfb_OBJECTS) $(mmpfb_DEPENDENCIES) $(EXTRA_mmpfb_DEPENDENCIES) @rm -f mmpfb$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(mmpfb_OBJECTS) $(mmpfb_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/myfont.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1minimize.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1rewrit.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-man uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-binPROGRAMS install-data install-data-am \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-man1 install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-binPROGRAMS uninstall-man uninstall-man1 .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lcdf-typetools-2.108/mmpfb/Makefile.am0000664000175000017500000000057412732752520014567 00000000000000## Process this file with automake to produce Makefile.in AUTOMAKE_OPTIONS = foreign bin_PROGRAMS = mmpfb man_MANS = mmpfb.1 mmpfb_SOURCES = myfont.cc myfont.hh \ main.cc \ t1minimize.cc t1minimize.hh \ t1rewrit.cc t1rewrit.hh mmpfb_LDADD = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_CPPFLAGS = -I$(srcdir)/../include CLEANFILES = @TEMPLATE_OBJS@ EXTRA_DIST = mmpfb.1 lcdf-typetools-2.108/mmpfb/t1rewrit.cc0000644000175000017500000005277413423375327014636 00000000000000/* t1rewrit.cc -- routines for multiple- to single-master charstring conversion * * Copyright (c) 1997-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include "t1rewrit.hh" #include #include #include #include #include #include using namespace Efont; static bool itc_complained = false; static ErrorHandler *itc_errh; void itc_complain() { //itc_errh->warning("strange %; is this an ITC font?"); itc_complained = true; } /***** * HintReplacementDetector **/ class HintReplacementDetector : public CharstringInterp { public: HintReplacementDetector(Type1Font *, int); HintReplacementDetector(Type1Font *, const Vector &, int); bool is_hint_replacement(int i) const { return _hint_replacements[i] != 0; } int call_count(int i) const { return _call_counts[i]; } bool type1_command(int); bool run(Type1Font *, Type1Charstring &); private: Vector _hint_replacements; Vector _call_counts; int _subr_level; int _count_calls_below; }; HintReplacementDetector::HintReplacementDetector(Type1Font *f, int b) : CharstringInterp(), _hint_replacements(f->nsubrs(), 0), _call_counts(f->nsubrs(), 0), _count_calls_below(b) { } HintReplacementDetector::HintReplacementDetector(Type1Font *f, const Vector &wv, int b) : CharstringInterp(wv), _hint_replacements(f->nsubrs(), 0), _call_counts(f->nsubrs(), 0), _count_calls_below(b) { } bool HintReplacementDetector::type1_command(int cmd) { switch (cmd) { case Cs::cCallothersubr: { if (size() < 2) goto unknown; int command = (int)top(0); int n = (int)top(1); if (command == Cs::othcReplacehints && n == 1) { pop(2); _hint_replacements[(int)top()] = 1; ps_clear(); ps_push(top()); pop(); break; } else if (command >= Cs::othcMM1 && command <= Cs::othcMM6) { pop(2); return mm_command(command, n); } else if (command >= Cs::othcITC_load && command <= Cs::othcITC_random) { pop(2); return itc_command(command, n); } else goto unknown; } case Cs::cCallsubr: { if (size() < 1) return error(errUnderflow, cmd); int which = (int)pop(); if (!_count_calls_below || _subr_level < _count_calls_below) _call_counts[which]++; Charstring *subr_cs = get_subr(which); if (!subr_cs) return error(errSubr, which); _subr_level++; subr_cs->process(*this); _subr_level--; if (error() != errOK) return false; return !done(); } case Cs::cEndchar: case Cs::cReturn: return CharstringInterp::type1_command(cmd); case Cs::cBlend: case Cs::cAbs: case Cs::cAdd: case Cs::cSub: case Cs::cDiv: case Cs::cNeg: case Cs::cRandom: case Cs::cMul: case Cs::cSqrt: case Cs::cDrop: case Cs::cExch: case Cs::cIndex: case Cs::cRoll: case Cs::cDup: case Cs::cAnd: case Cs::cOr: case Cs::cNot: case Cs::cEq: case Cs::cIfelse: return arith_command(cmd); case Cs::cPop: if (ps_size() >= 1) push(ps_pop()); break; default: unknown: clear(); break; } return true; } bool HintReplacementDetector::run(Type1Font *f, Type1Charstring &cs) { _subr_level = 0; CharstringInterp::interpret(f, &cs); return error() == errOK; } /***** * Type1OneMMRemover **/ class Type1OneMMRemover: public CharstringInterp { public: Type1OneMMRemover(Type1MMRemover *); bool type1_command(int); inline bool run_fresh_subr(const Type1Charstring &, bool); inline bool run_fresh_glyph(const Type1Charstring &); inline bool rerun_subr(const Type1Charstring &); Type1Charstring *output_prefix(); void output_main(Type1Charstring &); private: Type1MMRemover *_remover; Type1CharstringGen _prefix_gen; Type1CharstringGen _main_gen; int _subr_level; bool _in_subr; bool _in_prefix; bool _must_expand; inline void run_subr(Type1Charstring *); bool itc_command(int command, int on_stack); bool run(const Type1Charstring &, bool, bool, bool); }; /* For version 1.1 * * Problem: Sometimes a charstring will call one subroutine, which will call * another, etc., which finally does a multiple master CallOtherSubr! The * required arguments might build up only gradually over all the subrs. This * makes it hard to remove the eventual CallOtherSubr! * * Partial solution: Divide each subroutine into two parts: the initial * "prefix" contains the closure of any initial multiple-master commands * (including those from sub-subroutines), the following "main" part has all * the other commands. In a situation like this: * * subr-1 = 8 15 callothersubr pop pop pop return * subr-2 = 4 5 6 1 callsubr return * subr-3 = 1 2 3 2 callsubr return * * we'll divide it up like this: (prefix || main) * * subr-1 = 8 15 callothersubr pop pop pop || (nothing) * subr-2 = 4 5 6 8 15 callothersubr pop pop pop || (nothing) * subr-3 = 1 2 3 4 5 6 8 15 callothersubr pop pop pop || (nothing) * * Now, when we call a subroutine, we EXECUTE its prefix part. Then, if its * main part is nonempty, we output the original call to the subroutine to * take care of the main part. */ Type1OneMMRemover::Type1OneMMRemover(Type1MMRemover *remover) : CharstringInterp(remover->weight_vector()), _remover(remover), _prefix_gen(remover->precision()), _main_gen(remover->precision()) { } inline void Type1OneMMRemover::run_subr(Type1Charstring *cs) { _subr_level++; cs->process(*this); _subr_level--; } bool Type1OneMMRemover::itc_command(int command, int on_stack) { const Vector &weight = weight_vector(); assert(weight.size()); Vector *scratch = scratch_vector(); Type1CharstringGen *gen = (_in_prefix ? &_prefix_gen : (_in_subr ? &_main_gen : 0)); int base = size() - on_stack - 2; switch (command) { case Cs::othcITC_load: { if (on_stack != 1) return false; int offset = (int)at(base); for (int i = 0; i < weight.size(); i++) vec(scratch, offset+i) = weight.at_u(i); // save load command, so we expand its effects into the scratch // vector if (gen) { gen->gen_number(offset); gen->gen_number(1); gen->gen_number(Cs::othcITC_load); gen->gen_command(Cs::cCallothersubr); } break; } case Cs::othcITC_put: { if (on_stack != 2) return false; int offset = (int)at(base+1); vec(scratch, offset) = at(base); // save put command, so we expand its effects into the scratch // vector if (gen) { gen->gen_number(at(base)); gen->gen_number(offset); gen->gen_number(2); gen->gen_number(Cs::othcITC_put); gen->gen_command(Cs::cCallothersubr); } break; } case Cs::othcITC_get: { if (on_stack != 1) return false; int offset = (int)at(base); double d = vec(scratch, offset); if (!KNOWN(d)) { _must_expand = true; return false; } ps_push(d); break; } case Cs::othcITC_add: { if (on_stack != 2) return false; ps_push(at(base) + at(base+1)); break; } case Cs::othcITC_sub: { if (on_stack != 2) return false; ps_push(at(base) - at(base+1)); break; } case Cs::othcITC_mul: { if (on_stack != 2) return false; ps_push(at(base) * at(base+1)); break; } case Cs::othcITC_div: { if (on_stack != 2) return false; ps_push(at(base) / at(base+1)); break; } case Cs::othcITC_ifelse: { if (on_stack != 4) return false; if (at(base+2) <= at(base+3)) ps_push(at(base)); else ps_push(at(base+1)); break; } default: return false; } pop(on_stack + 2); return true; } bool Type1OneMMRemover::type1_command(int cmd) { switch (cmd) { case Cs::cCallothersubr: { // Expand known othersubr calls. If we cannot expand the othersubr // call completely, then write it to the expander. if (size() < 2) goto partial_othersubr; int command = (int)top(0); int n = (int)top(1); if (command >= Cs::othcITC_load && command <= Cs::othcITC_random) { if (!itc_complained) itc_complain(); if (size() < 2 + n || !itc_command(command, n)) goto partial_othersubr; } else if (command >= Cs::othcMM1 && command <= Cs::othcMM6) { if (size() < 2 + n) goto partial_othersubr; pop(2); mm_command(command, n); } else goto normal; break; } partial_othersubr: { if (!_in_prefix) { _must_expand = true; goto normal; } _prefix_gen.gen_stack(*this, 0); _prefix_gen.gen_command(Cs::cCallothersubr); break; } case Cs::cCallsubr: { // expand subroutines in line if necessary if (size() < 1) goto normal; int subrno = (int)pop(); if (_subr_level < 1) { // otherwise, have already included prefix if (Type1Charstring *cs = _remover->subr_prefix(subrno)) run_subr(cs); } if (Type1Charstring *cs = _remover->subr_expander(subrno)) run_subr(cs); else { push(subrno); goto normal; } break; } case Cs::cPop: if (ps_size() >= 1) push(ps_pop()); else if (_in_prefix && ps_size() == 0) { _prefix_gen.gen_stack(*this, 0); _prefix_gen.gen_command(Cs::cPop); } else goto normal; break; case Cs::cDiv: if (size() < 2) goto normal; top(1) /= top(0); pop(); break; case Cs::cReturn: return false; normal: default: _main_gen.gen_stack(*this, cmd); _main_gen.gen_command(cmd); _in_prefix = 0; return (cmd != Cs::cEndchar); } return true; } bool Type1OneMMRemover::run(const Type1Charstring &cs, bool in_subr, bool do_prefix, bool fresh) { _prefix_gen.clear(); _main_gen.clear(); _in_subr = in_subr; _in_prefix = do_prefix; _subr_level = (fresh ? 0 : 1); _must_expand = false; Vector *scratch = scratch_vector(); scratch->assign(scratch->size(), UNKDOUBLE); CharstringInterp::interpret(_remover->program(), &cs); if (in_subr) { _main_gen.gen_stack(*this, Cs::cReturn); _main_gen.gen_command(Cs::cReturn); } if (_must_expand) return true; if (fresh && in_subr) { if (_main_gen.length() == 0 || (_main_gen.length() == 1 && _main_gen.data()[0] == Cs::cReturn)) return true; } return false; } inline bool Type1OneMMRemover::run_fresh_subr(const Type1Charstring &cs, bool do_prefix) { return run(cs, true, do_prefix, true); } inline bool Type1OneMMRemover::run_fresh_glyph(const Type1Charstring &cs) { return run(cs, false, false, true); } inline bool Type1OneMMRemover::rerun_subr(const Type1Charstring &cs) { return run(cs, true, false, false); } Type1Charstring * Type1OneMMRemover::output_prefix() { if (_prefix_gen.length() > 0) { _prefix_gen.gen_command(Cs::cReturn); return _prefix_gen.output(); } else return 0; } void Type1OneMMRemover::output_main(Type1Charstring &cs) { _main_gen.output(cs); } /***** * Type1BadCallRemover **/ class Type1BadCallRemover: public CharstringInterp { public: Type1BadCallRemover(Type1MMRemover *); bool type1_command(int); bool run(Type1Charstring &, bool is_subr); private: Type1CharstringGen _gen; Type1MMRemover *_remover; bool _is_subr; }; Type1BadCallRemover::Type1BadCallRemover(Type1MMRemover *remover) : CharstringInterp(remover->weight_vector()), _gen(remover->precision()), _remover(remover) { } bool Type1BadCallRemover::type1_command(int cmd) { switch (cmd) { case Cs::cCallsubr: { if (size() < 1) goto normal; int subrno = (int)top(); if (!get_subr(subrno)) { pop(); return false; } else goto normal; } normal: default: _gen.gen_stack(*this, 0); _gen.gen_command(cmd); return (cmd != Cs::cEndchar || _is_subr) && cmd != Cs::cReturn; } } bool Type1BadCallRemover::run(Type1Charstring &cs, bool is_subr) { _is_subr = is_subr; _gen.clear(); CharstringInterp::interpret(_remover->program(), &cs); _gen.output(cs); return error() == errOK; } /***** * Type1MMRemover **/ Type1MMRemover::Type1MMRemover(Type1Font *font, const Vector &wv, int precision, ErrorHandler *errh) : _font(font), _weight_vector(wv), _precision(precision), _nsubrs(font->nsubrs()), _subr_done(_nsubrs, 0), _subr_prefix(_nsubrs, (Type1Charstring *)0), _must_expand_subr(_nsubrs, 0), _hint_replacement_subr(_nsubrs, 0), _expand_all_subrs(false), _errh(errh) { itc_errh = _errh; // find subroutines needed for hint replacement HintReplacementDetector hr(font, wv, 0); for (int i = 0; i < _font->nglyphs(); i++) if (Type1Subr *g = _font->glyph_x(i)) hr.run(font, g->t1cs()); for (int i = 0; i < _nsubrs; i++) if (hr.is_hint_replacement(i)) _hint_replacement_subr[i] = 1; // don't get rid of first 4 subrs for (int i = 0; i < _nsubrs && i < 4; i++) _subr_done[i] = 1; } Type1MMRemover::~Type1MMRemover() { for (int i = 0; i < _nsubrs; i++) if (_subr_prefix[i]) delete _subr_prefix[i]; } Type1Charstring * Type1MMRemover::subr_prefix(int subrno) { if (subrno < 0 || subrno >= _nsubrs) return 0; if (!_subr_done[subrno]) { _subr_done[subrno] = 1; Type1Charstring *subr = _font->subr(subrno); if (!subr) return 0; Type1OneMMRemover one(this); if (one.run_fresh_subr(*subr, !_hint_replacement_subr[subrno])) _must_expand_subr[subrno] = true; _subr_prefix[subrno] = one.output_prefix(); one.output_main(*subr); } return _subr_prefix[subrno]; } Type1Charstring * Type1MMRemover::subr_expander(int subrno) { if (subrno < 0 || subrno >= _nsubrs) return 0; if (!_subr_done[subrno]) (void)subr_prefix(subrno); if (!_expand_all_subrs && !_must_expand_subr[subrno]) return 0; return _font->subr(subrno); } extern "C" { static int CDECL sort_permstring_compare(const void *v1, const void *v2) { const PermString *s1 = (const PermString *)v1; const PermString *s2 = (const PermString *)v2; return strcmp(s1->c_str(), s2->c_str()); } } void Type1MMRemover::run() { Type1OneMMRemover one(this); // check subroutines for (int subrno = 0; subrno < _nsubrs; subrno++) (void)subr_prefix(subrno); // expand glyphs Vector bad_glyphs; for (int i = 0; i < _font->nglyphs(); i++) { Type1Subr *g = _font->glyph_x(i); if (g) { if (one.run_fresh_glyph(g->t1cs())) { // Every glyph should be fully expandable without encountering // a MM command. If we fail the first time, try again, // expanding ALL subroutines. This catches, for example, SUBR // 1 { 1 0 return }; GLYPH g { 1 callsubr 2 blend }; This will // fail the first time, because `1 callsubr' will be left as a // subroutine call, so `1 0' (required arguments to `blend') // won't be visible. _expand_all_subrs = true; if (one.run_fresh_glyph(g->t1cs())) bad_glyphs.push_back(g->name()); _expand_all_subrs = false; } one.output_main(g->t1cs()); } } // remove uncalled subroutines, expand hint replacement subroutines HintReplacementDetector hr(_font, _weight_vector, 0); for (int i = 0; i < _font->nglyphs(); i++) if (Type1Subr *g = _font->glyph_x(i)) hr.run(_font, g->t1cs()); // don't remove first four subroutines! for (int subrno = 4; subrno < _nsubrs; subrno++) if (hr.call_count(subrno) || _hint_replacement_subr[subrno]) { Type1Charstring *cs = _font->subr(subrno); if (one.rerun_subr(*cs)) { _expand_all_subrs = true; if (one.rerun_subr(*cs)) bad_glyphs.push_back(permprintf("subr %d", subrno)); _expand_all_subrs = false; } one.output_main(*cs); } else _font->remove_subr(subrno); // remove calls to removed subroutines Type1BadCallRemover bcr(this); for (int i = 0; i < _font->nglyphs(); i++) if (Type1Subr *g = _font->glyph_x(i)) bcr.run(g->t1cs(), false); for (int subrno = 4; subrno < _nsubrs; subrno++) if (Type1Charstring *cs = _font->subr(subrno)) bcr.run(*cs, true); // report warnings if (bad_glyphs.size()) { qsort(&bad_glyphs[0], bad_glyphs.size(), sizeof(PermString), sort_permstring_compare); _errh->error("could not fully interpolate the following glyphs:"); StringAccum sa; for (int i = 0; i < bad_glyphs.size(); i++) { PermString n = bad_glyphs[i]; bool comma = (i < bad_glyphs.size() - 1); if (sa.length() && sa.length() + 1 + n.length() + comma > 70) { _errh->message(" %s", sa.c_str()); sa.clear(); } sa << (sa.length() ? " " : "") << n << (comma ? "," : ""); } _errh->message(" %s", sa.c_str()); } } /***** * SubrExpander **/ class SubrExpander : public CharstringInterp { public: SubrExpander(); void set_renumbering(const Vector *v) { _renumbering = v; } bool type1_command(int); bool run(Type1Font *, Type1Charstring &); private: Type1CharstringGen _gen; const Vector *_renumbering; int _subr_level; }; SubrExpander::SubrExpander() : CharstringInterp(), _gen(0), _renumbering(0) { } bool SubrExpander::type1_command(int cmd) { switch (cmd) { case Cs::cCallsubr: { if (size() < 1) goto unknown; int subrno = (int)top(0); int renumber_subrno = (subrno >= 0 && subrno < _renumbering->size() ? (*_renumbering)[subrno] : subrno); if (renumber_subrno >= 0) { top(0) = renumber_subrno; goto unknown; } pop(); if (Charstring *subr_cs = get_subr(subrno)) { _subr_level++; subr_cs->process(*this); _subr_level--; } return !done(); } case Cs::cEndchar: set_done(); goto end_cs; case Cs::cReturn: if (_subr_level) return false; goto end_cs; end_cs: _gen.gen_stack(*this, cmd); _gen.gen_command(cmd); return false; default: unknown: _gen.gen_stack(*this, cmd); _gen.gen_command(cmd); break; } return true; } bool SubrExpander::run(Type1Font *font, Type1Charstring &cs) { _gen.clear(); _subr_level = 0; CharstringInterp::interpret(font, &cs); _gen.output(cs); return error() == errOK; } /***** * Type1SubrRemover **/ Type1SubrRemover::Type1SubrRemover(Type1Font *font, ErrorHandler *errh) : _font(font), _nsubrs(font->nsubrs()), _renumbering(_nsubrs, REMOVABLE), _cost(_nsubrs, 0), _save_count(0), _nonexist_count(0), _errh(errh) { // find subroutines needed for hint replacement HintReplacementDetector hr(font, 2); for (int i = 0; i < _font->nglyphs(); i++) { Type1Subr *g = _font->glyph_x(i); if (g) hr.run(_font, g->t1cs()); } // save necessary subroutines for (int i = 0; i < 4; i++) { _renumbering[i] = i; _save_count++; } // save hint-replacement subroutines for (int i = 0; i < _nsubrs; i++) { Type1Subr *cs = _font->subr_x(i); if (!cs) { _renumbering[i] = DEAD; _nonexist_count++; } else if (hr.is_hint_replacement(i)) { _renumbering[i] = i; _save_count++; } else _cost[i] = hr.call_count(i) * (cs->t1cs().length() - (i <= 107 ? 2 : 3)); } } Type1SubrRemover::~Type1SubrRemover() { } static Vector *sort_keys; extern "C" { static int CDECL sort_permute_compare(const void *v1, const void *v2) { const int *i1 = (const int *)v1; const int *i2 = (const int *)v2; return (*sort_keys)[*i1] - (*sort_keys)[*i2]; } } bool Type1SubrRemover::run(int lower_to) { if (lower_to < 0) lower_to = _nsubrs; if (lower_to < _save_count) { _errh->warning("reducing %s to minimum number of subroutines (%d)", _font->font_name().c_str(), _save_count - _nonexist_count); lower_to = _save_count; } int to_remove = _nsubrs - _nonexist_count - lower_to; if (to_remove < 0) to_remove = 0; // multiply by lost bytes per call Vector permute; for (int i = 0; i < _nsubrs; i++) permute.push_back(i); // sort them by least frequent use -> most frequent use sort_keys = &_cost; qsort(&permute[0], _nsubrs, sizeof(int), sort_permute_compare); // mark first portion of `permute' to be removed int removed = 0; for (int i = 0; i < _nsubrs; i++) { int p = permute[i]; if (_renumbering[p] == REMOVABLE && removed < to_remove) { _renumbering[p] = DEAD; removed++; } } // renumber the rest int renumber_pos = 0; for (int i = 0; i < _nsubrs; i++) if (_renumbering[i] == REMOVABLE) { // save it while (_renumbering[renumber_pos] >= 0) renumber_pos++; _renumbering[i] = renumber_pos++; } SubrExpander rem0; rem0.set_renumbering(&_renumbering); // go through and change them all for (int i = 0; i < _nsubrs; i++) { Type1Subr *s = _font->subr_x(i); if (s && _renumbering[i] >= 0) rem0.run(_font, s->t1cs()); } for (int i = 0; i < _font->nglyphs(); i++) if (Type1Subr *g = _font->glyph_x(i)) rem0.run(_font, g->t1cs()); // actually remove subroutines _font->renumber_subrs(_renumbering); return true; } lcdf-typetools-2.108/mmpfb/myfont.hh0000664000175000017500000000157412732752520014371 00000000000000#ifndef MYFONT_HH #define MYFONT_HH #include namespace Efont { class MultipleMasterSpace; } class ErrorHandler; class MyFont : public Efont::Type1Font { public: MyFont(Efont::Type1Reader &); ~MyFont(); bool set_design_vector(Efont::MultipleMasterSpace *, const Vector &, ErrorHandler * = 0); void interpolate_dicts(bool force_integers, ErrorHandler *); void interpolate_charstrings(int precision, ErrorHandler * = 0); private: typedef Vector NumVector; int _nmasters; Vector _weight_vector; void interpolate_dict_int(PermString, Dict, ErrorHandler *); void interpolate_dict_num(PermString, Dict, bool round_integer = false); void interpolate_dict_numvec(PermString, Dict, int round_mode = 0, bool executable = false); void kill_def(Efont::Type1Definition *, int which_dict = -1); }; #endif lcdf-typetools-2.108/texglyphlist.txt0000664000175000017500000002376312732752520014740 00000000000000# lcdf-typetools texglyphlist.txt, Version 2.95 # Contents: Extensions to the Adobe Glyph List for TeX fonts and # encodings. We also extend the second field so that it can contain # multiple Unicode scalar values, separated by commas, analogous to # otftotfm's "% UNICODING" comments. ############################################################################### Delta;2206,0394 Ifractur;2111 FFsmall;F766 F766,0066 0066 FFIsmall;F766 F766 F769,0066 0066 0069 FFLsmall;F766 F766 F76C,0066 0066 006C FIsmall;F766 F769,0066 0069 FLsmall;F766 F76C,0066 006C Germandbls;0053 0053 Germandblssmall;F773 F773,0073 0073 Ng;014A Omega;2126,03A9 Rfractur;211C SS;0053 0053 SSsmall;F773 F773,0073 0073 # altselector: invalid Unicode altselector;D802 angbracketleft;27E8,2329 angbracketright;27E9,232A arrowbothv;2195 arrowdblbothv;21D5 arrowleftbothalf;21BD arrowlefttophalf;21BC arrownortheast;2197 arrownorthwest;2196 arrowrightbothalf;21C1 arrowrighttophalf;21C0 arrowsoutheast;2198 arrowsouthwest;2199 # ascendercompwordmark: taller cwm, invalid Unicode ascendercompwordmark;D80A asteriskcentered;2217 bardbl;2225 # capitalcompwordmark: taller cwm, invalid Unicode capitalcompwordmark;D809 ceilingleft;2308 ceilingright;2309 circlecopyrt;20DD,25CB circledivide;2298 circledot;2299 circleminus;2296 coproduct;2A3F ct;0063 0074 # cwm: Unicode for ZWNJ, used for secondary replacement from EC.enc cwm;200C dblbracketleft;27E6 dblbracketright;27E7 # U+2662 is WHITE DIAMOND SUIT # U+25CA is LOZENGE # U+2666 is BLACK DIAMOND SUIT diamond;2662,25CA,2666 diamondmath;22C4 # U+0237 is the proposed allocation for dotless j as of Unicode 4.0 # U+1D6A5 is the mathematical italic version approved in Unicode 5.0 dotlessj;0237,F6BE,1D6A5 emptyset;2205,F638 # emptyslot: invalid Unicode; the user explicitly wants this slot empty emptyslot;D801 epsilon1;03F5 epsiloninv;03F6 equivasymptotic;224D flat;266D floorleft;230A floorright;230B follows;227B followsequal;2AB0 followsorcurly;227D greatermuch;226B heart;2661,2665 interrobang;203D interrobangdown;2E18 intersectionsq;2293 latticetop;22A4 lessmuch;226A longdbls;017F 017F longsh;017F 0068 longsi;017F 0069 longsl;017F 006C longst;FB05,017F 0074 lscript;2113 natural;266E negationslash;0338 ng;014B owner;220B pertenthousand;2031 # TeX encodings such as 'texmital.enc' disagree with Unicode and the Adobe # glyph list; in TeX, the "straight" form of phi takes the name "phi", # whereas the more-common "loopy" form of phi, \varphi, takes the name "phi1". phi;03D5,03C6 phi1;03C6 pi1;03D6 precedesequal;2AAF precedesorcurly;227C prime;2032,02B9 rho1;03F1 # ringfitted: a ring character centered on the x-width of A, invalid Unicode ringfitted;D80D sharp;266F similarequal;2243 slurabove;2322 slurbelow;2323 st;FB06,0073 0074 star;22C6 subsetsqequal;2291 supersetsqequal;2292 triangle;25B3 triangleinv;25BD triangleleft;25C1 triangleright;25B7 turnstileleft;22A2 turnstileright;22A3 # twelveudash: 2/3-em dash; invalid Unicode twelveudash;D80C unionmulti;228E unionsq;2294 vector;20D7 # visualspace: Unicode for OPEN BOX, used for secondary replacement from EC.enc visualspace;2423 wreathproduct;2240 # -- Marco Kuhlmann reported annoying glyph neologisms in fontinst encodings # Dbar = Dcroat Dbar;0110 # compwordmark = cwm compwordmark;200C # dbar = dcroat dbar;0111 # rangedash = endash rangedash;2013 # hyphenchar = hyphen hyphenchar;002D # punctdash = emdash punctdash;2014 # visiblespace = visualspace visiblespace;2423 # -- # -- These character names are used in the MSAM fonts # -- Yen;00A5 # the MSAM10 glyph is more closed than U+21BA # the MSAM10 glyph's gap is at the top, while U+27F2 is on the left anticlockwise;27F2,21BA # XXX arrowaxisleft # XXX arrowaxisright arrowparrleftright;21C6 arrowparrrightleft;21C4 arrowtailleft;21A2 arrowtailright;21A3 arrowtripleleft;21DA arrowtripleright;21DB # XXX axisshort between;226C # U+2713 is a Zapf dingbat check;2713 circleR;00AE # the MSAM10 glyph may be smaller than U+24C8 circleS;24C8 circleasterisk;229B circleequal;229C circlering;229A # the MSAM10 glyph is more closed than U+21BB # the MSAM10 glyph's gap is at the top, while U+27F3 is on the left clockwise;27F3,21BB complement;2201 curlyleft;21AB curlyright;21AC dblarrowdwn;21CA dblarrowheadleft;219E dblarrowheadright;21A0 dblarrowup;21C8 defines;225C # U+2666 is BLACK DIAMOND SUIT # U+29EB is BLACK LOZENGE diamondsolid;2666,29EB difference;224F dotplus;2214 downfall;22CE equaldotleftright;2252 equaldotrightleft;2253 equalorfollows;22DF equalorgreater;2A96 equalorless;2A95 equalorprecedes;22DE equalsdots;2251 followsorequal;227F forces;22A9 forcesbar;22AA fork;22D4 frown;2322 geomequivalent;224E greaterdbleqlless;2A8C greaterdblequal;2267 greaterlessequal;22DB greaterorapproxeql;2A86 greaterorequalslant;2A7E greaterorsimilar;2273 harpoondownleft;21C3 harpoondownright;21C2 # MSAM probably misnamed this glyph; the right pointing harpoon is above # U+21CC has the right pointing harpoon above, like MSAM harpoonleftright;21CC # MSAM probably misnamed this glyph; the left pointing harpoon is above # U+21CB has the left pointing harpoon above, like MSAM harpoonrightleft;21CB harpoonupleft;21BF harpoonupright;21BE # U+22BA may be larger than MSAM intercal intercal;22BA intersectiondbl;22D2 lessdbleqlgreater;2A8B lessdblequal;2266 lessequalgreater;22DA lessorapproxeql;2A85 lessorequalslant;2A7D lessorsimilar;2272 maltesecross;2720 measuredangle;2221 multimap;22B8 multiopenleft;22CB multiopenright;22CC nand;22BC orunderscore;22BB # U+2306 PERSPECTIVE is larger than the MSAM glyph perpcorrespond;2A5E,2306 precedesorequal;227E primereverse;2035 revasymptequal;22CD revsimilar;223D # U+231D TOP RIGHT CORNER is a quine corner, # U+2E23 TOP RIGHT HALF BRACKET is a half bracket. # MSAM rightanglene matches the shape of U+231C but the spacing of U+2E23. # Similar for other rightangle characters. rightanglene;231D,2E23 rightanglenw;231C,2E22 rightanglese;231F,2E25 rightanglesw;231E,2E24 ringinequal;2256 # U+22A7 MODELS is shorter than U+22A8 TRUE = satisfies. # MSAM satisfies is in between. satisfies;22A8 shiftleft;21B0 shiftright;21B1 smile;2323 sphericalangle;2222 # U+25A1 WHITE SQUARE square;25A1 squaredot;22A1 squareimage;228F squareminus;229F squaremultiply;22A0 squareoriginal;2290 squareplus;229E # XXX U+25AA BLACK SMALL SQUARE doesn't sit on the baseline # XXX squaresmallsolid squaresolid;25A0 # U+21AD LEFT RIGHT WAVE ARROW is not actually a squiggle arrow squiggleleftright;21AD squiggleright;21DD subsetdbl;22D0 subsetdblequal;2AC5 supersetdbl;22D1 supersetdblequal;2AC6 triangledownsld;25BC # U+22B4 NORMAL SUBGROUP OF OR EQUAL TO is sharper than MSAM triangleleftequal;22B4,25C1 0332 triangleleftsld;25C0 # U+22B5 CONTAINS AS NORMAL SUBGROUP OR EQUAL TO is sharper than MSAM trianglerightequal;22B5,25B7 0332 trianglerightsld;25B6 trianglesolid;25B2 uniondbl;22D3 uprise;22CF # -- # -- These character names are used in the MSBM fonts # -- # U+1D7CB MATHEMATICAL BOLD SMALL DIGAMMA is the closest match to MSBM, # although MSBM Digamma's spelling indicates that a capital was intended # U+03DD GREEK SMALL LETTER DIGAMMA for fallback Digamma;1D7CB,03DD # U+2132 TURNED CAPITAL F is shown as seriffed, MSBM Finv is sans Finv;2132 # U+2141 TURNED SANS-SERIF CAPITAL G is turned, MSBM Gmir is only reversed Gmir;2141 Omegainv;2127 approxorequal;224A archleftdown;21B6 archrightdown;21B7 # XXX barshort beth;2136 daleth;2138 dividemultiply;22C7 # U+29F9 BIG REVERSE SOLIDUS seems the right size downslope;29F9 equalorsimilar;2242 follownotdbleqv;2ABA follownotslnteql;2AB6 followornoteqvlnt;22E9 greaterdot;22D7 # MSBM misnamed this glyph; should be greaternotdbleqv greaternotdblequal;2A8A greaternotequal;2A88 greaterornotdbleql;2269 # XXX MSBM greaterornotequal has a vertical negation slash, not U+2269 diagonal greaterornotequal;2269 # XXX greaterornotsimilar # XXX hatwide # XXX hatwider integerdivide;2216 lessdot;22D6 # MSBM misnamed this glyph; should be lessnotdbleqv lessnotdblequal;2A89 lessnotequal;2A87 lessornotdbleql;2268 # XXX MSBM lessornotequal has a vertical negation slash, not U+2268 diagonal lessornotequal;2268 # XXX lessornotsimilar multicloseleft;22C9 multicloseright;22CA notapproxequal;2247 notarrowboth;21AE notarrowleft;219A notarrowright;219B notbar;2224 notdblarrowboth;21CE notdblarrowleft;21CD notdblarrowright;21CF notexistential;2204 notfollows;2281 # U+22E1 DOES NOT SUCCEED OR EQUAL has a curved equal sign, unlike MSBM notfollowsoreql;2AB0 0338,22E1 notforces;22AE notforcesextra;22AF # Unicode has no precomposed negation of U+2267 GREATER THAN OVER EQUAL TO notgreaterdblequal;2267 0338 notgreaterequal;2271 notgreaterorslnteql;2A7E 0338 notlessdblequal;2266 0338 notlessequal;2270 notlessorslnteql;2A7D 0338 # U+22E0 DOES NOT PRECEDE OR EQUAL has a curved equal sign, unlike MSBM notprecedesoreql;2AAF 0338,22E0 notsatisfies;22AD # XXX notshortbar # XXX notshortparallel notsimilar;2241 notsubseteql;2288 notsubsetordbleql;2AC5 0338 # U+228A SUBSET OF WITH NOT EQUAL TO negation slash only touches bar below; # MSBM negation slash touches bar and lower part of subset notsubsetoreql;228A notsuperseteql;2289 notsupersetordbleql;2AC6 0338 # U+228A SUPERSET OF WITH NOT EQUAL TO negation slash only touches bar below; # MSBM negation slash touches bar and lower part of superset notsupersetoreql;228B # U+22EC NOT NORMAL SUBGROUP OF OR EQUAL TO is sharper than MSBM nottriangeqlleft;22EC,25C1 0332 0338 # U+22ED DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL is sharper than MSBM nottriangeqlright;22ED,25B7 0332 0338 # U+22EA NOT NORMAL SUBGROUP OF is sharper than MSBM nottriangleleft;22EA,25C1 0338 # U+22EB DOES NOT CONTAIN AS NORMAL SUBGROUP is sharper than MSBM nottriangleright;22EB,25B7 0338 notturnstile;22AC # XXX parallelshort planckover2pi;210F # U+210F PLANCK CONSTANT OVER TWO PI is shown with diagonal slash, which # corresponds to MSBM planckover2pi, but this is a font variant planckover2pi1;210F precedenotdbleqv;2AB9 precedenotslnteql;2AB5 precedeornoteqvlnt;22E8 subsetnoteql;228A subsetornotdbleql;2ACB # XXX subsetornoteql supersetnoteql;228B supersetornotdbleql;2ACC # XXX supersetornoteql # XXX tildewide # XXX tildewider # U+29F8 BIG SOLIDUS seems the right size upslope;29F8 lcdf-typetools-2.108/t1reencode/0000755000175000017500000000000013423377073013537 500000000000000lcdf-typetools-2.108/t1reencode/util.cc0000644000175000017500000000402613423375330014737 00000000000000/* util.{cc,hh} -- various bits * * Copyright (c) 2003-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include "util.hh" #include #include #include #include #include #include #if defined(_MSDOS) || defined(_WIN32) # include # include #endif String read_file(String filename, ErrorHandler *errh, bool warning) { FILE *f; if (!filename || filename == "-") { filename = ""; f = stdin; #if defined(_MSDOS) || defined(_WIN32) // Set the file mode to binary _setmode(_fileno(f), _O_BINARY); #endif } else if (!(f = fopen(filename.c_str(), "rb"))) { errh->xmessage((warning ? errh->e_warning : errh->e_error) + ErrorHandler::make_landmark_anno(filename), strerror(errno)); return String(); } StringAccum sa; int amt; do { if (char *x = sa.reserve(8192)) { amt = fread(x, 1, 8192, f); sa.adjust_length(amt); } else amt = 0; } while (amt != 0); if (!feof(f) || ferror(f)) errh->xmessage((warning ? errh->e_warning : errh->e_error) + ErrorHandler::make_landmark_anno(filename), strerror(errno)); if (f != stdin) fclose(f); return sa.take_string(); } String printable_filename(const String &s) { if (!s || s == "-") return String::make_stable(""); else return s; } String pathname_filename(const String &path) { int slash = path.find_right('/'); if (slash >= 0 && slash != path.length() - 1) return path.substring(slash + 1); else return path; } lcdf-typetools-2.108/t1reencode/util.hh0000664000175000017500000000041012732752520014746 00000000000000#ifndef T1REENCODE_UTIL_HH #define T1REENCODE_UTIL_HH #include class ErrorHandler; String read_file(String filename, ErrorHandler *, bool warn = false); String printable_filename(const String &); String pathname_filename(const String &); #endif lcdf-typetools-2.108/t1reencode/t1reencode.cc0000644000175000017500000015166513423375330016027 00000000000000/* t1reencode.cc -- driver for reencoding Type 1 fonts * * Copyright (c) 2005-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include "util.hh" #include #ifdef HAVE_CTIME # include #endif #if defined(_MSDOS) || defined(_WIN32) # include # include #endif using namespace Efont; #define VERSION_OPT 301 #define HELP_OPT 302 #define OUTPUT_OPT 303 #define ENCODING_OPT 304 #define ENCODING_TEXT_OPT 305 #define PFA_OPT 306 #define PFB_OPT 307 #define FONTNAME_OPT 308 #define FULLNAME_OPT 309 const Clp_Option options[] = { { "help", 'h', HELP_OPT, 0, 0 }, { "output", 'o', OUTPUT_OPT, Clp_ValString, 0 }, { "pfa", 'a', PFA_OPT, 0, 0 }, { "pfb", 'b', PFB_OPT, 0, 0 }, { "name", 'n', FONTNAME_OPT, Clp_ValString, 0 }, { "fullname", 'N', FULLNAME_OPT, Clp_ValString, 0 }, { "full-name", 'N', FULLNAME_OPT, Clp_ValString, 0 }, { "encoding", 'e', ENCODING_OPT, Clp_ValString, 0 }, { "encoding-text", 'E', ENCODING_TEXT_OPT, Clp_ValString, 0 }, { "version", 0, VERSION_OPT, 0, 0 }, }; static const char *program_name; static PermString::Initializer initializer; static HashMap glyph_order(-1); static String encoding_name; static const char ISOLatin1Encoding[] = "/ISOLatin1Encoding [\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright\n\ /parenleft /parenright /asterisk /plus /comma /minus /period /slash\n\ /zero /one /two /three /four /five /six /seven\n\ /eight /nine /colon /semicolon /less /equal /greater /question\n\ /at /A /B /C /D /E /F /G\n\ /H /I /J /K /L /M /N /O\n\ /P /Q /R /S /T /U /V /W\n\ /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore\n\ /quoteleft /a /b /c /d /e /f /g\n\ /h /i /j /k /l /m /n /o\n\ /p /q /r /s /t /u /v /w\n\ /x /y /z /braceleft /bar /braceright /asciitilde /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /dotlessi /grave /acute /circumflex /tilde /.notdef /breve /dotaccent\n\ /.notdef /.notdef /ring /.notdef /.notdef /hungarumlaut /ogonek /caron\n\ /.notdef /exclamdown /cent /sterling /currency /yen /brokenbar /section\n\ /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron\n\ /degree /plusminus /twosuperior /threesuperior /.notdef /mu /paragraph /periodcentered\n\ /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown\n\ /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla\n\ /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis\n\ /Eth /Ntilde /Ograve /Oacute /Ocircumflex /.notdef /Odieresis /multiply\n\ /Oslash /.notdef /.notdef /.notdef /.notdef /Yacute /Thorn /germandbls\n\ /agrave /aacute /acircumflex /atilde /.notdef /aring /ae /ccedilla\n\ /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis\n\ /eth /ntilde /.notdef /oacute /ocircumflex /otilde /odieresis /.notdef\n\ /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn\n\ ] def\n"; static const char ISOLatin2Encoding[] = "/ISOLatin2Encoding [\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle\n\ /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash\n\ /zero /one /two /three /four /five /six /seven\n\ /eight /nine /colon /semicolon /less /equal /greater /question\n\ /at /A /B /C /D /E /F /G\n\ /H /I /J /K /L /M /N /O\n\ /P /Q /R /S /T /U /V /W\n\ /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore\n\ /grave /a /b /c /d /e /f /g\n\ /h /i /j /k /l /m /n /o\n\ /p /q /r /s /t /u /v /w\n\ /x /y /z /braceleft /bar /braceright /asciitilde /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /uni00A0 /Aogonek /breve /Lslash /currency /Lcaron /Sacute /section\n\ /dieresis /Scaron /Scedilla /Tcaron /Zacute /uni00AD /Zcaron /Zdotaccent\n\ /degree /aogonek /ogonek /lslash /acute /lcaron /sacute /caron\n\ /cedilla /scaron /scedilla /tcaron /zacute /hungarumlaut /zcaron /zdotaccent\n\ /Racute /Aacute /Acircumflex /Abreve /Adieresis /Lacute /Cacute /Ccedilla\n\ /Ccaron /Eacute /Eogonek /Edieresis /Ecaron /Iacute /Icircumflex /Dcaron\n\ /Dcroat /Nacute /Ncaron /Oacute /Ocircumflex /Ohungarumlaut /Odieresis /multiply\n\ /Rcaron /Uring /Uacute /Uhungarumlaut /Udieresis /Yacute /uni0162 /germandbls\n\ /racute /aacute /acircumflex /abreve /adieresis /lacute /cacute /ccedilla\n\ /ccaron /eacute /eogonek /edieresis /ecaron /iacute /icircumflex /dcaron\n\ /dcroat /nacute /ncaron /oacute /ocircumflex /ohungarumlaut /odieresis /divide\n\ /rcaron /uring /uacute /uhungarumlaut /udieresis /yacute /uni0163 /dotaccent\n\ ] def\n"; static const char ISOLatin3Encoding[] = "/ISOLatin3Encoding [\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle\n\ /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash\n\ /zero /one /two /three /four /five /six /seven\n\ /eight /nine /colon /semicolon /less /equal /greater /question\n\ /at /A /B /C /D /E /F /G\n\ /H /I /J /K /L /M /N /O\n\ /P /Q /R /S /T /U /V /W\n\ /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore\n\ /grave /a /b /c /d /e /f /g\n\ /h /i /j /k /l /m /n /o\n\ /p /q /r /s /t /u /v /w\n\ /x /y /z /braceleft /bar /braceright /asciitilde /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /uni00A0 /Hbar /breve /sterling /currency /yen /Hcircumflex /section\n\ /dieresis /Idotaccent /Scedilla /Gbreve /Jcircumflex /uni00AD /registered /Zdotaccent\n\ /degree /hbar /twosuperior /threesuperior /acute /mu /hcircumflex /periodcentered\n\ /cedilla /dotlessi /scedilla /gbreve /jcircumflex /onehalf /threequarters /zdotaccent\n\ /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Cdotaccent /Ccircumflex /Ccedilla\n\ /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis\n\ /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Gdotaccent /Odieresis /multiply\n\ /Gcircumflex /Ugrave /Uacute /Ucircumflex /Udieresis /Ubreve /Scircumflex /germandbls\n\ /agrave /aacute /acircumflex /atilde /adieresis /cdotaccent /ccircumflex /ccedilla\n\ /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis\n\ /eth /ntilde /ograve /oacute /ocircumflex /gdotaccent /odieresis /divide\n\ /gcircumflex /ugrave /uacute /ucircumflex /udieresis /ubreve /scircumflex /dotaccent\n\ ] def\n"; static const char ISOLatin4Encoding[] = "/ISOLatin4Encoding [\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle\n\ /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash\n\ /zero /one /two /three /four /five /six /seven\n\ /eight /nine /colon /semicolon /less /equal /greater /question\n\ /at /A /B /C /D /E /F /G\n\ /H /I /J /K /L /M /N /O\n\ /P /Q /R /S /T /U /V /W\n\ /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore\n\ /grave /a /b /c /d /e /f /g\n\ /h /i /j /k /l /m /n /o\n\ /p /q /r /s /t /u /v /w\n\ /x /y /z /braceleft /bar /braceright /asciitilde /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /uni00A0 /Aogonek /kgreenlandic /Rcommaaccent /currency /Itilde /Lcommaaccent /section\n\ /dieresis /Scaron /Emacron /Gcommaaccent /Tbar /uni00AD /Zcaron /macron\n\ /degree /aogonek /ogonek /rcommaaccent /acute /itilde /lcommaaccent /caron\n\ /cedilla /scaron /emacron /gcommaaccent /tbar /Eng /zcaron /eng\n\ /Amacron /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Iogonek\n\ /Ccaron /Eacute /Eogonek /Edieresis /Edotaccent /Iacute /Icircumflex /Imacron\n\ /Dcroat /Ncommaaccent /Omacron /Kcommaaccent /Ocircumflex /Otilde /Odieresis /multiply\n\ /Oslash /Uogonek /Uacute /Ucircumflex /Udieresis /Utilde /Umacron /germandbls\n\ /amacron /aacute /acircumflex /atilde /adieresis /aring /ae /iogonek\n\ /ccaron /eacute /eogonek /edieresis /edotaccent /iacute /icircumflex /imacron\n\ /dcroat /ncommaaccent /omacron /kcommaaccent /ocircumflex /otilde /odieresis /divide\n\ /oslash /uogonek /uacute /ucircumflex /udieresis /utilde /umacron /dotaccent\n\ ] def\n"; static const char ISOCyrillicEncoding[] = "/ISOCyrillicEncoding [\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle\n\ /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash\n\ /zero /one /two /three /four /five /six /seven\n\ /eight /nine /colon /semicolon /less /equal /greater /question\n\ /at /A /B /C /D /E /F /G\n\ /H /I /J /K /L /M /N /O\n\ /P /Q /R /S /T /U /V /W\n\ /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore\n\ /grave /a /b /c /d /e /f /g\n\ /h /i /j /k /l /m /n /o\n\ /p /q /r /s /t /u /v /w\n\ /x /y /z /braceleft /bar /braceright /asciitilde /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /uni00A0 /afii10023 /afii10051 /afii10052 /afii10053 /afii10054 /afii10055 /afii10056\n\ /afii10057 /afii10058 /afii10059 /afii10060 /afii10061 /uni00AD /afii10062 /afii10145\n\ /afii10017 /afii10018 /afii10019 /afii10020 /afii10021 /afii10022 /afii10024 /afii10025\n\ /afii10026 /afii10027 /afii10028 /afii10029 /afii10030 /afii10031 /afii10032 /afii10033\n\ /afii10034 /afii10035 /afii10036 /afii10037 /afii10038 /afii10039 /afii10040 /afii10041\n\ /afii10042 /afii10043 /afii10044 /afii10045 /afii10046 /afii10047 /afii10048 /afii10049\n\ /afii10065 /afii10066 /afii10067 /afii10068 /afii10069 /afii10070 /afii10072 /afii10073\n\ /afii10074 /afii10075 /afii10076 /afii10077 /afii10078 /afii10079 /afii10080 /afii10081\n\ /afii10082 /afii10083 /afii10084 /afii10085 /afii10086 /afii10087 /afii10088 /afii10089\n\ /afii10090 /afii10091 /afii10092 /afii10093 /afii10094 /afii10095 /afii10096 /afii10097\n\ /afii61352 /afii10071 /afii10099 /afii10100 /afii10101 /afii10102 /afii10103 /afii10104\n\ /afii10105 /afii10106 /afii10107 /afii10108 /afii10109 /section /afii10110 /afii10193\n\ ] def\n"; static const char ISOGreekEncoding[] = "/ISOGreekEncoding [\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle\n\ /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash\n\ /zero /one /two /three /four /five /six /seven\n\ /eight /nine /colon /semicolon /less /equal /greater /question\n\ /at /A /B /C /D /E /F /G\n\ /H /I /J /K /L /M /N /O\n\ /P /Q /R /S /T /U /V /W\n\ /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore\n\ /grave /a /b /c /d /e /f /g\n\ /h /i /j /k /l /m /n /o\n\ /p /q /r /s /t /u /v /w\n\ /x /y /z /braceleft /bar /braceright /asciitilde /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /uni00A0 /afii64937 /afii57929 /sterling /currency /yen /brokenbar /section\n\ /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /uni00AD /registered /afii00208\n\ /degree /plusminus /twosuperior /threesuperior /tonos /dieresistonos /Alphatonos /periodcentered\n\ /Epsilontonos /Etatonos /Iotatonos /guillemotright /Omicrontonos /onehalf /Upsilontonos /Omegatonos\n\ /iotadieresistonos /Alpha /Beta /Gamma /uni0394 /Epsilon /Zeta /Eta\n\ /Theta /Iota /Kappa /Lambda /Mu /Nu /Xi /Omicron\n\ /Pi /Rho /Ograve /Sigma /Tau /Upsilon /Phi /Chi\n\ /Psi /uni03A9 /Iotadieresis /Upsilondieresis /alphatonos /epsilontonos /etatonos /iotatonos\n\ /upsilondieresistonos /alpha /beta /gamma /delta /epsilon /zeta /eta\n\ /theta /iota /kappa /lambda /uni03BC /nu /xi /omicron\n\ /pi /rho /sigma1 /sigma /tau /upsilon /phi /chi\n\ /psi /omega /iotadieresis /upsilondieresis /omicrontonos /upsilontonos /omegatonos /ydieresis\n\ ] def\n"; static const char ISOLatin5Encoding[] = "/ISOLatin5Encoding [\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle\n\ /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash\n\ /zero /one /two /three /four /five /six /seven\n\ /eight /nine /colon /semicolon /less /equal /greater /question\n\ /at /A /B /C /D /E /F /G\n\ /H /I /J /K /L /M /N /O\n\ /P /Q /R /S /T /U /V /W\n\ /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore\n\ /grave /a /b /c /d /e /f /g\n\ /h /i /j /k /l /m /n /o\n\ /p /q /r /s /t /u /v /w\n\ /x /y /z /braceleft /bar /braceright /asciitilde /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /uni00A0 /exclamdown /cent /sterling /currency /yen /brokenbar /section\n\ /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /uni00AD /registered /macron\n\ /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered\n\ /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown\n\ /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla\n\ /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis\n\ /Gbreve /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply\n\ /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Idotaccent /Scedilla /germandbls\n\ /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla\n\ /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis\n\ /gbreve /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide\n\ /oslash /ugrave /uacute /ucircumflex /udieresis /dotlessi /scedilla /ydieresis\n\ ] def\n"; static const char ISOLatin6Encoding[] = "/ISOLatin6Encoding [\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle\n\ /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash\n\ /zero /one /two /three /four /five /six /seven\n\ /eight /nine /colon /semicolon /less /equal /greater /question\n\ /at /A /B /C /D /E /F /G\n\ /H /I /J /K /L /M /N /O\n\ /P /Q /R /S /T /U /V /W\n\ /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore\n\ /grave /a /b /c /d /e /f /g\n\ /h /i /j /k /l /m /n /o\n\ /p /q /r /s /t /u /v /w\n\ /x /y /z /braceleft /bar /braceright /asciitilde /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /uni00A0 /Aogonek /Emacron /Gcommaaccent /Imacron /Itilde /Kcommaaccent /section\n\ /Lcommaaccent /Dcroat /Scaron /Tbar /Zcaron /uni00AD /Umacron /Eng\n\ /degree /aogonek /emacron /gcommaaccent /imacron /itilde /kcommaaccent /periodcentered\n\ /lcommaaccent /dcroat /scaron /tbar /zcaron /macron /umacron /eng\n\ /Amacron /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Iogonek\n\ /Ccaron /Eacute /Eogonek /Edieresis /Emacron /Iacute /Icircumflex /Idieresis\n\ /Eth /Ncommaaccent /Omacron /Oacute /Ocircumflex /Otilde /Odieresis /Utilde\n\ /Oslash /Uogonek /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls\n\ /amacron /aacute /acircumflex /atilde /adieresis /aring /ae /iogonek\n\ /ccaron /eacute /eogonek /edieresis /emacron /iacute /icircumflex /idieresis\n\ /eth /ncommaaccent /omacron /oacute /ocircumflex /otilde /odieresis /utilde\n\ /oslash /uogonek /uacute /ucircumflex /udieresis /yacute /thorn /kgreenlandic\n\ ] def\n"; static const char ISOThaiEncoding[] = "/ISOThaiEncoding [\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle\n\ /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash\n\ /zero /one /two /three /four /five /six /seven\n\ /eight /nine /colon /semicolon /less /equal /greater /question\n\ /at /A /B /C /D /E /F /G\n\ /H /I /J /K /L /M /N /O\n\ /P /Q /R /S /T /U /V /W\n\ /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore\n\ /grave /a /b /c /d /e /f /g\n\ /h /i /j /k /l /m /n /o\n\ /p /q /r /s /t /u /v /w\n\ /x /y /z /braceleft /bar /braceright /asciitilde /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /uni00A0 /uni0E01 /uni0E02 /uni0E03 /uni0E04 /uni0E05 /uni0E06 /uni0E07\n\ /uni0E08 /uni0E09 /uni0E0A /uni0E0B /uni0E0C /uni0E0D /uni0E0E /uni0E0F\n\ /uni0E10 /uni0E11 /uni0E12 /uni0E13 /uni0E14 /uni0E15 /uni0E16 /uni0E17\n\ /uni0E18 /uni0E19 /uni0E1A /uni0E1B /uni0E1C /uni0E1D /uni0E1E /uni0E1F\n\ /uni0E20 /uni0E21 /uni0E22 /uni0E23 /uni0E24 /uni0E25 /uni0E26 /uni0E27\n\ /uni0E28 /uni0E29 /uni0E2A /uni0E2B /uni0E2C /uni0E2D /uni0E2E /uni0E2F\n\ /uni0E30 /uni0E31 /uni0E32 /uni0E33 /uni0E34 /uni0E35 /uni0E36 /uni0E37\n\ /uni0E38 /uni0E39 /uni0E3A /.notdef /space /.notdef /.notdef /uni0E3F\n\ /uni0E40 /uni0E41 /uni0E42 /uni0E43 /uni0E44 /uni0E45 /uni0E46 /uni0E47\n\ /uni0E48 /uni0E49 /uni0E4A /uni0E4B /uni0E4C /uni0E4D /uni0E4E /uni0E4F\n\ /uni0E50 /uni0E51 /uni0E52 /uni0E53 /uni0E54 /uni0E55 /uni0E56 /uni0E57\n\ /uni0E58 /uni0E59 /uni0E5A /.notdef /.notdef /.notdef /.notdef /.notdef\n\ ] def\n"; static const char ISOLatin7Encoding[] = "/ISOLatin7Encoding [\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle\n\ /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash\n\ /zero /one /two /three /four /five /six /seven\n\ /eight /nine /colon /semicolon /less /equal /greater /question\n\ /at /A /B /C /D /E /F /G\n\ /H /I /J /K /L /M /N /O\n\ /P /Q /R /S /T /U /V /W\n\ /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore\n\ /grave /a /b /c /d /e /f /g\n\ /h /i /j /k /l /m /n /o\n\ /p /q /r /s /t /u /v /w\n\ /x /y /z /braceleft /bar /braceright /asciitilde /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /uni00A0 /quotedblright /cent /sterling /currency /quotedblbase /brokenbar /section\n\ /Oslash /copyright /rcommaaccent /guillemotleft /logicalnot /uni00AD /registered /AE\n\ /degree /plusminus /twosuperior /threesuperior /quotedblleft /mu /paragraph /periodcentered\n\ /oslash /onesuperior /.notdef /guillemotright /onequarter /onehalf /threequarters /ae\n\ /Aogonek /Iogonek /Amacron /Cacute /Adieresis /Aring /Eogonek /Emacron\n\ /Ccaron /Eacute /Zacute /Edotaccent /Gcommaaccent /Kcommaaccent /Imacron /Lcommaaccent\n\ /Scaron /Nacute /Ncommaaccent /Oacute /Omacron /Otilde /Odieresis /multiply\n\ /Uogonek /Lslash /Uacute /Ucircumflex /Udieresis /Zdotaccent /Zcaron /germandbls\n\ /aogonek /Iogonek /amacron /cacute /adieresis /aring /eogonek /emacron\n\ /ccaron /eacute /zacute /edotaccent /gcommaaccent /kcommaaccent /imacron /lcommaaccent\n\ /scaron /nacute /ncommaaccent /oacute /omacron /otilde /odieresis /divide\n\ /uogonek /lslash /uacute /ucircumflex /udieresis /zdotaccent /zcaron /quoteright\n\ ] def\n"; static const char ISOLatin8Encoding[] = "/ISOLatin8Encoding [\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle\n\ /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash\n\ /zero /one /two /three /four /five /six /seven\n\ /eight /nine /colon /semicolon /less /equal /greater /question\n\ /at /A /B /C /D /E /F /G\n\ /H /I /J /K /L /M /N /O\n\ /P /Q /R /S /T /U /V /W\n\ /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore\n\ /grave /a /b /c /d /e /f /g\n\ /h /i /j /k /l /m /n /o\n\ /p /q /r /s /t /u /v /w\n\ /x /y /z /braceleft /bar /braceright /asciitilde /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /uni00A0 /uni1E02 /uni1E03 /sterling /Cdotaccent /cdotaccent /uni1E0A /section\n\ /Wgrave /copyright /Wacute /uni1E0B /Ygrave /uni00AD /registered /Ydieresis\n\ /uni1E1E /uni1E1F /Gdotaccent /gdotaccent /uni1E40 /uni1E41 /paragraph /uni1E56\n\ /wgrave /uni1E57 /wacute /uni1E60 /ygrave /Wdieresis /wdieresis /uni1E61\n\ /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla\n\ /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis\n\ /Wcircumflex /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /uni1E6A\n\ /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Ycircumflex /germandbls\n\ /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla\n\ /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis\n\ /wcircumflex /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /uni1E6B\n\ /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /ycircumflex /ydieresis\n\ ] def\n"; static const char ISOLatin9Encoding[] = "/ISOLatin9Encoding [\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle\n\ /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash\n\ /zero /one /two /three /four /five /six /seven\n\ /eight /nine /colon /semicolon /less /equal /greater /question\n\ /at /A /B /C /D /E /F /G\n\ /H /I /J /K /L /M /N /O\n\ /P /Q /R /S /T /U /V /W\n\ /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore\n\ /grave /a /b /c /d /e /f /g\n\ /h /i /j /k /l /m /n /o\n\ /p /q /r /s /t /u /v /w\n\ /x /y /z /braceleft /bar /braceright /asciitilde /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /uni00A0 /exclamdown /cent /sterling /Euro /yen /Scaron /section\n\ /scaron /copyright /ordfeminine /guillemotleft /logicalnot /uni00AD /registered /macron\n\ /degree /plusminus /twosuperior /threesuperior /Zcaron /mu /paragraph /periodcentered\n\ /zcaron /onesuperior /ordmasculine /guillemotright /OE /oe /Ydieresis /questiondown\n\ /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla\n\ /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis\n\ /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply\n\ /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls\n\ /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla\n\ /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis\n\ /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide\n\ /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis\n\ ] def\n"; static const char KOI8REncoding[] = "/KOI8REncoding [\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle\n\ /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash\n\ /zero /one /two /three /four /five /six /seven\n\ /eight /nine /colon /semicolon /less /equal /greater /question\n\ /at /A /B /C /D /E /F /G\n\ /H /I /J /K /L /M /N /O\n\ /P /Q /R /S /T /U /V /W\n\ /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore\n\ /grave /a /b /c /d /e /f /g\n\ /h /i /j /k /l /m /n /o\n\ /p /q /r /s /t /u /v /w\n\ /x /y /z /braceleft /bar /braceright /asciitilde /.notdef\n\ /SF100000 /SF110000 /SF010000 /SF030000 /SF020000 /SF040000 /SF080000 /SF090000\n\ /SF060000 /SF070000 /SF050000 /upblock /dnblock /block /lfblock /rtblock\n\ /ltshade /shade /dkshade /integraltp /filledbox /uni2219 /radical /approxequal\n\ /lessequal /greaterequal /uni00A0 /integralbt /degree /twosuperior /periodcentered /divide\n\ /SF430000 /SF240000 /SF510000 /afii10071 /SF520000 /SF390000 /SF220000 /SF210000\n\ /SF250000 /SF500000 /SF490000 /SF380000 /SF280000 /SF270000 /SF260000 /SF360000\n\ /SF370000 /SF420000 /SF190000 /afii10023 /SF200000 /SF230000 /SF470000 /SF480000\n\ /SF410000 /SF450000 /SF460000 /SF400000 /SF540000 /SF530000 /SF440000 /copyright\n\ /afii10096 /afii10065 /afii10066 /afii10088 /afii10069 /afii10070 /afii10086 /afii10068\n\ /afii10087 /afii10074 /afii10075 /afii10076 /afii10077 /afii10078 /afii10079 /afii10080\n\ /afii10081 /afii10097 /afii10082 /afii10083 /afii10084 /afii10085 /afii10072 /afii10067\n\ /afii10094 /afii10093 /afii10073 /afii10090 /afii10095 /afii10091 /afii10089 /afii10092\n\ /afii10048 /afii10017 /afii10018 /afii10040 /afii10021 /afii10022 /afii10038 /afii10020\n\ /afii10039 /afii10026 /afii10027 /afii10028 /afii10029 /afii10030 /afii10031 /afii10032\n\ /afii10033 /afii10049 /afii10034 /afii10035 /afii10036 /afii10037 /afii10024 /afii10019\n\ /afii10046 /afii10045 /afii10025 /afii10042 /afii10047 /afii10043 /afii10041 /afii10044\n\ ] def\n"; static const char ExpertEncoding[] = "/ExpertEncoding [\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /space /exclamsmall /Hungarumlautsmall /.notdef /dollaroldstyle /dollarsuperior /ampersandsmall /Acutesmall\n\ /parenleftsuperior /parenrightsuperior /twodotenleader /onedotenleader /comma /hyphen /period /fraction\n\ /zerooldstyle /oneoldstyle /twooldstyle /threeoldstyle /fouroldstyle /fiveoldstyle /sixoldstyle /sevenoldstyle\n\ /eightoldstyle /nineoldstyle /colon /semicolon /commasuperior /threequartersemdash /periodsuperior /questionsmall\n\ /.notdef /asuperior /bsuperior /centsuperior /dsuperior /esuperior /.notdef /.notdef\n\ /.notdef /isuperior /.notdef /.notdef /lsuperior /msuperior /nsuperior /osuperior\n\ /.notdef /.notdef /rsuperior /ssuperior /tsuperior /.notdef /ff /fi\n\ /fl /ffi /ffl /parenleftinferior /.notdef /parenrightinferior /Circumflexsmall /hyphensuperior\n\ /Gravesmall /Asmall /Bsmall /Csmall /Dsmall /Esmall /Fsmall /Gsmall\n\ /Hsmall /Ismall /Jsmall /Ksmall /Lsmall /Msmall /Nsmall /Osmall\n\ /Psmall /Qsmall /Rsmall /Ssmall /Tsmall /Usmall /Vsmall /Wsmall\n\ /Xsmall /Ysmall /Zsmall /colonmonetary /onefitted /rupiah /Tildesmall /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /exclamdownsmall /centoldstyle /Lslashsmall /.notdef /.notdef /Scaronsmall /Zcaronsmall\n\ /Dieresissmall /Brevesmall /Caronsmall /.notdef /Dotaccentsmall /.notdef /.notdef /Macronsmall\n\ /.notdef /.notdef /figuredash /hypheninferior /.notdef /.notdef /Ogoneksmall /Ringsmall\n\ /Cedillasmall /.notdef /.notdef /.notdef /onequarter /onehalf /threequarters /questiondownsmall\n\ /oneeighth /threeeighths /fiveeighths /seveneighths /onethird /twothirds /.notdef /.notdef\n\ /zerosuperior /onesuperior /twosuperior /threesuperior /foursuperior /fivesuperior /sixsuperior /sevensuperior\n\ /eightsuperior /ninesuperior /zeroinferior /oneinferior /twoinferior /threeinferior /fourinferior /fiveinferior\n\ /sixinferior /seveninferior /eightinferior /nineinferior /centinferior /dollarinferior /periodinferior /commainferior\n\ /Agravesmall /Aacutesmall /Acircumflexsmall /Atildesmall /Adieresissmall /Aringsmall /AEsmall /Ccedillasmall\n\ /Egravesmall /Eacutesmall /Ecircumflexsmall /Edieresissmall /Igravesmall /Iacutesmall /Icircumflexsmall /Idieresissmall\n\ /Ethsmall /Ntildesmall /Ogravesmall /Oacutesmall /Ocircumflexsmall /Otildesmall /Odieresissmall /OEsmall\n\ /Oslashsmall /Ugravesmall /Uacutesmall /Ucircumflexsmall /Udieresissmall /Yacutesmall /Thornsmall\n\ ] def\n"; static const char ExpertSubsetEncoding[] = "/ExpertSubsetEncoding [\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /space /.notdef /.notdef /.notdef /dollaroldstyle /dollarsuperior /.notdef /.notdef\n\ /parenleftsuperior /parenrightsuperior /twodotenleader /onedotenleader /comma /hyphen /period /fraction\n\ /zerooldstyle /oneoldstyle /twooldstyle /threeoldstyle /fouroldstyle /fiveoldstyle /sixoldstyle /sevenoldstyle\n\ /eightoldstyle /nineoldstyle /colon /semicolon /commasuperior /threequartersemdash /periodsuperior /.notdef\n\ /.notdef /asuperior /bsuperior /centsuperior /dsuperior /esuperior /.notdef /.notdef\n\ /.notdef /isuperior /.notdef /.notdef /lsuperior /msuperior /nsuperior /osuperior\n\ /.notdef /.notdef /rsuperior /ssuperior /tsuperior /.notdef /ff /fi\n\ /fl /ffi /ffl /parenleftinferior /.notdef /parenrightinferior /.notdef /hyphensuperior\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /colonmonetary /onefitted /rupiah /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /centoldstyle /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /figuredash /hypheninferior /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /onequarter /onehalf /threequarters /.notdef\n\ /oneeighth /threeeighths /fiveeighths /seveneighths /onethird /twothirds /.notdef /.notdef\n\ /zerosuperior /onesuperior /twosuperior /threesuperior /foursuperior /fivesuperior /sixsuperior /sevensuperior\n\ /eightsuperior /ninesuperior /zeroinferior /oneinferior /twoinferior /threeinferior /fourinferior /fiveinferior\n\ /sixinferior /seveninferior /eightinferior /nineinferior /centinferior /dollarinferior /periodinferior /commainferior\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ ] def\n"; static const char SymbolEncoding[] = "/SymbolEncoding [\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /space /exclam /universal /numbersign /existential /percent /ampersand /suchthat\n\ /parenleft /parenright /asteriskmath /plus /comma /minus /period /slash\n\ /zero /one /two /three /four /five /six /seven\n\ /eight /nine /colon /semicolon /less /equal /greater /question\n\ /congruent /Alpha /Beta /Chi /Delta /Epsilon /Phi /Gamma\n\ /Eta /Iota /theta1 /Kappa /Lambda /Mu /Nu /Omicron\n\ /Pi /Theta /Rho /Sigma /Tau /Upsilon /sigma1 /Omega\n\ /Xi /Psi /Zeta /bracketleft /therefore /bracketright /perpendicular /underscore\n\ /radicalex /alpha /beta /chi /delta /epsilon /phi /gamma\n\ /eta /iota /phi1 /kappa /lambda /mu /nu /omicron\n\ /pi /theta /rho /sigma /tau /upsilon /omega1 /omega\n\ /xi /psi /zeta /braceleft /bar /braceright /similar /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n\ /.notdef /Upsilon1 /minute /lessequal /fraction /infinity /florin /club\n\ /diamond /heart /spade /arrowboth /arrowleft /arrowup /arrowright /arrowdown\n\ /degree /plusminus /second /greaterequal /multiply /proportional /partialdiff /bullet\n\ /divide /notequal /equivalence /approxequal /ellipsis /arrowvertex /arrowhorizex /carriagereturn\n\ /aleph /Ifraktur /Rfraktur /weierstrass /circlemultiply /circleplus /emptyset /intersection\n\ /union /propersuperset /reflexsuperset /notsubset /propersubset /reflexsubset /element /notelement\n\ /angle /gradient /registerserif /copyrightserif /trademarkserif /product /radical /dotmath\n\ /logicalnot /logicaland /logicalor /arrowdblboth /arrowdblleft /arrowdblup /arrowdblright /arrowdbldown\n\ /lozenge /angleleft /registersans /copyrightsans /trademarksans /summation /parenlefttp /parenleftex\n\ /parenleftbt /bracketlefttp /bracketleftex /bracketleftbt /bracelefttp /braceleftmid /braceleftbt /braceex\n\ /.notdef /angleright /integral /integraltp /integralex /integralbt /parenrighttp /parenrightex\n\ /parenrightbt /bracketrighttp /bracketrightex /bracketrightbt /bracerighttp /bracerightmid /bracerightbt\n\ ] def\n"; void usage_error(ErrorHandler *errh, const char *error_message, ...) { va_list val; va_start(val, error_message); if (!error_message) errh->message("Usage: %s [OPTION]... FONT", program_name); else errh->xmessage(ErrorHandler::e_error, error_message, val); errh->message("Type %s --help for more information.", program_name); exit(1); } void usage() { FileErrorHandler uerrh(stdout); uerrh.message("\ % changes a Type 1 font%,s embedded encoding and writes the\n\ reencoded font to the standard output.\n\ \n\ Usage: %s [OPTION]... [FONTFILE [OUTPUTFILE]]\n\ \n\ Options:\n\ -e, --encoding=FILE Read the encoding from FILE (in DVIPS format).\n\ -E, --encoding-text=ENC The ENC argument is the encoding text.\n\ -n, --name=NAME Set output font%,s PostScript name.\n\ -N, --full-name=NAME Set output font%,s full name.\n\ -a, --pfa Output PFA font.\n\ -b, --pfb Output PFB font. This is the default.\n\ -o, --output=FILE Write output to FILE instead of standard out.\n\ -h, --help Print this message and exit.\n\ --version Print version number and exit.\n\ \n\ Report bugs to .\n", program_name); } // FONT MANIPULATION static void kill_def(Type1Font* font, Type1Definition *t1d, int whichd) { if (!t1d || font->dict(whichd, t1d->name()) != t1d) return; int icount = font->nitems(); for (int i = font->first_dict_item(whichd); i < icount; i++) if (font->item(i) == t1d) { StringAccum sa; sa << '%'; t1d->gen(sa); PermString name = t1d->name(); Type1CopyItem *t1ci = new Type1CopyItem(sa.take_string()); font->set_item(i, t1ci); font->set_dict(whichd, name, 0); return; } assert(0); } static void adjust_font_definitions(Type1Font* font, Type1Encoding* encoding, String new_name, String new_full_name) { // prepare an MD5 digest over the encoding StringAccum etext; for (int i = 0; i < 256; i++) etext << encoding->elt(i) << ' '; MD5_CONTEXT md5; md5_init(&md5); md5_update(&md5, (const unsigned char*) etext.data(), etext.length() - 1); // save UniqueID, then kill its definition int uniqueid; Type1Definition *t1d = font->dict("UniqueID"); bool have_uniqueid = (t1d && t1d->value_int(uniqueid)); kill_def(font, t1d, Type1Font::dFont); kill_def(font, font->p_dict("UniqueID"), Type1Font::dPrivate); // prepare XUID t1d = font->dict("XUID"); Vector xuid; if (!t1d || !t1d->value_numvec(xuid)) { if (have_uniqueid) { t1d = font->ensure(Type1Font::dFont, "XUID"); xuid.clear(); xuid.push_back(1); xuid.push_back(uniqueid); } else if (t1d) { kill_def(font, t1d, Type1Font::dFont); t1d = 0; } } if (t1d) { uint8_t digest[MD5_DIGEST_SIZE + 2]; // leave 2 bytes of space md5_final((unsigned char *) digest, &md5); digest[MD5_DIGEST_SIZE] = digest[MD5_DIGEST_SIZE + 1] = 0; // append digest to XUID; each element must be less than 2^24 for (int i = 0; i < MD5_DIGEST_SIZE; i += 3) xuid.push_back((digest[i] << 16) | (digest[i+1] << 8) | digest[i+2]); t1d->set_numvec(xuid); } // prepare new font name if (!encoding_name) { char text_digest[MD5_TEXT_DIGEST_SIZE + 1]; md5_final_text(text_digest, &md5); encoding_name = "AutoEnc_" + String(text_digest); } t1d = font->dict("FontName"); PermString name; if (t1d && t1d->value_name(name)) { if (!new_name) new_name = name + encoding_name; t1d->set_name(new_name.c_str()); font->uncache_defs(); // remove cached font name } // add a FullName too String full_name; t1d = font->fi_dict("FullName"); if (t1d && t1d->value_string(full_name)) { if (!new_full_name) new_full_name = full_name + "_" + encoding_name + " Enc"; t1d->set_string(new_full_name.c_str()); } // add header comments { StringAccum sa; #if HAVE_CTIME time_t cur_time = time(0); char *time_str = ctime(&cur_time); sa << "%% Created by t1reencode-" VERSION " on " << time_str; sa.pop_back(); #else sa << "%% Created by t1reencode-" VERSION "."; #endif font->add_header_comment(sa.take_string().c_str()); font->add_header_comment("%% T1reencode is free software. See ."); } } // ENCODING READER static String tokenize(const String &s, int &pos_in, int &line) { const char *data = s.data(); int len = s.length(); int pos = pos_in; while (1) { // skip whitespace while (pos < len && isspace((unsigned char) data[pos])) { if (data[pos] == '\n') line++; else if (data[pos] == '\r' && (pos + 1 == len || data[pos+1] != '\n')) line++; pos++; } if (pos >= len) { pos_in = len; return String(); } else if (data[pos] == '%') { for (pos++; pos < len && data[pos] != '\n' && data[pos] != '\r'; pos++) /* nada */; } else if (data[pos] == '[' || data[pos] == ']' || data[pos] == '{' || data[pos] == '}') { pos_in = pos + 1; return s.substring(pos, 1); } else if (data[pos] == '(') { int first = pos, nest = 0; for (pos++; pos < len && (data[pos] != ')' || nest); pos++) switch (data[pos]) { case '(': nest++; break; case ')': nest--; break; case '\\': if (pos + 1 < len) pos++; break; case '\n': line++; break; case '\r': if (pos + 1 == len || data[pos+1] != '\n') line++; break; } pos_in = (pos < len ? pos + 1 : len); return s.substring(first, pos_in - first); } else { int first = pos; while (pos < len && data[pos] == '/') pos++; while (pos < len && data[pos] != '/' && !isspace((unsigned char) data[pos]) && data[pos] != '[' && data[pos] != ']' && data[pos] != '%' && data[pos] != '(' && data[pos] != '{' && data[pos] != '}') pos++; pos_in = pos; return s.substring(first, pos - first); } } } static String landmark(const String &filename, int line) { return filename + String::make_stable(":", 1) + String(line); } Type1Encoding * parse_encoding(String s, String filename, ErrorHandler *errh) { filename = printable_filename(filename); int pos = 0, line = 1; // parse text String token = tokenize(s, pos, line); if (!token || token[0] != '/') { errh->lerror(landmark(filename, line), "parse error, expected name"); return 0; } encoding_name = token.substring(1); if (tokenize(s, pos, line) != "[") { errh->lerror(landmark(filename, line), "parse error, expected ["); return 0; } Type1Encoding *t1e = new Type1Encoding; int e = 0; while ((token = tokenize(s, pos, line)) && token[0] == '/') { if (e > 255) { errh->lwarning(landmark(filename, line), "more than 256 characters in encoding"); break; } t1e->put(e, token.substring(1)); e++; } return t1e; } // MAIN /***** * MAIN PROGRAM **/ static Type1Font * do_file(const char *filename, PsresDatabase *psres, ErrorHandler *errh) { FILE *f; if (!filename || strcmp(filename, "-") == 0) { f = stdin; filename = ""; #if defined(_MSDOS) || defined(_WIN32) _setmode(_fileno(f), _O_BINARY); #endif } else f = fopen(filename, "rb"); if (!f) { // check for PostScript name Filename fn = psres->filename_value("FontOutline", filename); f = fn.open_read(); } if (!f) errh->fatal("%s: %s", filename, strerror(errno)); Type1Reader *reader; int c = getc(f); ungetc(c, f); if (c == EOF) errh->fatal("%s: empty file", filename); if (c == 128) reader = new Type1PFBReader(f); else reader = new Type1PFAReader(f); Type1Font *font = new Type1Font(*reader); if (!font->ok()) errh->fatal("%s: no glyphs in font", filename); delete reader; return font; } int main(int argc, char *argv[]) { PsresDatabase *psres = new PsresDatabase; psres->add_psres_path(getenv("PSRESOURCEPATH"), 0, false); Clp_Parser *clp = Clp_NewParser(argc, (const char * const *)argv, sizeof(options) / sizeof(options[0]), options); program_name = Clp_ProgramName(clp); ErrorHandler *errh = ErrorHandler::static_initialize(new FileErrorHandler(stderr)); const char *input_file = 0; const char *output_file = 0; const char *encoding_file = 0; const char *encoding_text = 0; const char *new_font_name = 0; const char *new_full_name = 0; bool binary = true; Vector glyph_patterns; while (1) { int opt = Clp_Next(clp); switch (opt) { case ENCODING_OPT: if (encoding_file || encoding_text) errh->fatal("encoding already specified"); encoding_file = clp->vstr; break; case ENCODING_TEXT_OPT: if (encoding_file || encoding_text) errh->fatal("encoding already specified"); encoding_text = clp->vstr; break; case FONTNAME_OPT: if (new_font_name) errh->fatal("font name already specified"); new_font_name = clp->vstr; break; case FULLNAME_OPT: if (new_full_name) errh->fatal("full name already specified"); new_full_name = clp->vstr; break; case OUTPUT_OPT: if (output_file) errh->fatal("output file already specified"); output_file = clp->vstr; break; case PFA_OPT: binary = false; break; case PFB_OPT: binary = true; break; case VERSION_OPT: printf("t1reencode (LCDF typetools) %s\n", VERSION); printf("Copyright (C) 1999-2019 Eddie Kohler\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); exit(0); break; case HELP_OPT: usage(); exit(0); break; case Clp_NotOption: if (input_file && output_file) errh->fatal("too many arguments"); else if (input_file) output_file = clp->vstr; else input_file = clp->vstr; break; case Clp_Done: goto done; case Clp_BadOption: usage_error(errh, 0); break; default: break; } } done: // read the font Type1Font *font = do_file(input_file, psres, errh); if (!input_file || strcmp(input_file, "-") == 0) input_file = ""; // read the encoding if (!encoding_file && !encoding_text) errh->fatal("missing %<-e ENCODING%> argument"); Type1Encoding *t1e = 0; if (strcmp(encoding_file, "StandardEncoding") == 0) { t1e = Type1Encoding::standard_encoding(); encoding_name = encoding_file; } else { String text; if (strcmp(encoding_file, "ISOLatin1Encoding") == 0 || strcmp(encoding_file, "ISO_8859_1_Encoding") == 0) text = String::make_stable(ISOLatin1Encoding); else if (strcmp(encoding_file, "ISOLatin2Encoding") == 0 || strcmp(encoding_file, "ISO_8859_2_Encoding") == 0) text = String::make_stable(ISOLatin2Encoding); else if (strcmp(encoding_file, "ISOLatin3Encoding") == 0 || strcmp(encoding_file, "ISO_8859_3_Encoding") == 0) text = String::make_stable(ISOLatin3Encoding); else if (strcmp(encoding_file, "ISOLatin4Encoding") == 0 || strcmp(encoding_file, "ISO_8859_4_Encoding") == 0) text = String::make_stable(ISOLatin4Encoding); else if (strcmp(encoding_file, "ISOCyrillicEncoding") == 0 || strcmp(encoding_file, "ISO_8859_5_Encoding") == 0) text = String::make_stable(ISOCyrillicEncoding); else if (strcmp(encoding_file, "ISOGreekEncoding") == 0 || strcmp(encoding_file, "ISO_8859_7_Encoding") == 0) text = String::make_stable(ISOGreekEncoding); else if (strcmp(encoding_file, "ISO_8859_9_Encoding") == 0 || strcmp(encoding_file, "ISOLatin5Encoding") == 0) text = String::make_stable(ISOLatin5Encoding); else if (strcmp(encoding_file, "ISOLatin6Encoding") == 0 || strcmp(encoding_file, "ISO_8859_10_Encoding") == 0) text = String::make_stable(ISOLatin6Encoding); else if (strcmp(encoding_file, "ISOThaiEncoding") == 0 || strcmp(encoding_file, "ISO_8859_11_Encoding") == 0) text = String::make_stable(ISOThaiEncoding); else if (strcmp(encoding_file, "ISOLatin7Encoding") == 0 || strcmp(encoding_file, "ISO_8859_13_Encoding") == 0) text = String::make_stable(ISOLatin7Encoding); else if (strcmp(encoding_file, "ISOLatin8Encoding") == 0 || strcmp(encoding_file, "ISO_8859_14_Encoding") == 0) text = String::make_stable(ISOLatin8Encoding); else if (strcmp(encoding_file, "ISOLatin9Encoding") == 0 || strcmp(encoding_file, "ISO_8859_15_Encoding") == 0) text = String::make_stable(ISOLatin9Encoding); else if (strcmp(encoding_file, "KOI8REncoding") == 0) text = String::make_stable(KOI8REncoding); else if (strcmp(encoding_file, "ExpertEncoding") == 0) text = String::make_stable(ExpertEncoding); else if (strcmp(encoding_file, "ExpertSubsetEncoding") == 0) text = String::make_stable(ExpertSubsetEncoding); else if (strcmp(encoding_file, "SymbolEncoding") == 0) text = String::make_stable(SymbolEncoding); else if (encoding_text) text = String::make_stable(encoding_text), encoding_file = ""; else if ((text = read_file(encoding_file, errh)), errh->nerrors() > 0) exit(1); if (!(t1e = parse_encoding(text, encoding_file, errh))) exit(1); } // set the encoding font->add_type1_encoding(t1e); // adjust definitions adjust_font_definitions(font, t1e, new_font_name, new_full_name); // write it to output FILE *outf; if (!output_file || strcmp(output_file, "-") == 0) outf = stdout; else { outf = fopen(output_file, "w"); if (!outf) errh->fatal("%s: %s", output_file, strerror(errno)); } if (binary) { #if defined(_MSDOS) || defined(_WIN32) _setmode(_fileno(outf), _O_BINARY); #endif Type1PFBWriter w(outf); font->write(w); } else { Type1PFAWriter w(outf); font->write(w); } return (errh->nerrors() == 0 ? 0 : 1); } lcdf-typetools-2.108/t1reencode/t1reencode.10000644000175000017500000001013013423376706015567 00000000000000.ds V 2.108 .de M .BR "\\$1" "(\\$2)\\$3" .. .de Sp .if n .sp .if t .sp 0.4 .. .TH T1REENCODE 1 "LCDF Typetools" "Version \*V" .SH NAME t1reencode \- re-encode a PostScript Type 1 font .SH SYNOPSIS .B t1reencode \%\-e ENCODING \%[OPTIONS...] .I font .RI [ outputfile ] .SH DESCRIPTION .BR T1reencode changes a PostScript Type\~1 font's embedded encoding. The re-encoded font is written to the standard output (but see the .B \-\-output option). If no input font file is supplied, .B t1reencode reads a PFA or PFB font from the standard input. ' .SH OPTIONS .PD 0 .TP 5 .BR \-\-encoding "=\fIfile\fR, " \-e " \fIfile" Read the encoding from .IR file , which must contain an encoding in .M dvips 1 format. Alternatively, .I file can be one of the following special names, in which case the corresponding standard encoding is used. .Sp .RS .TP 23 .B Name .B Source .TP StandardEncoding Adobe .TP ISOLatin1Encoding Adobe/ISO (synonym: ISO_8859_1_Encoding) .TP ExpertEncoding Adobe .TP ExpertSubsetEncoding Adobe .TP SymbolEncoding Adobe .TP ISOLatin2Encoding ISO (synonym: ISO_8859_2_Encoding) .TP ISOLatin3Encoding ISO (synonym: ISO_8859_3_Encoding) .TP ISOLatin4Encoding ISO (synonym: ISO_8859_4_Encoding) .TP ISOCyrillicEncoding ISO (synonym: ISO_8859_5_Encoding) .TP ISOGreekEncoding ISO (synonym: ISO_8859_7_Encoding) .TP ISOLatin5Encoding ISO (synonym: ISO_8859_9_Encoding) .TP ISOLatin6Encoding ISO (synonym: ISO_8859_10_Encoding) .TP ISOThaiEncoding ISO (synonym: ISO_8859_11_Encoding) .TP ISOLatin7Encoding ISO (synonym: ISO_8859_13_Encoding) .TP ISOLatin8Encoding ISO (synonym: ISO_8859_14_Encoding) .TP ISOLatin9Encoding ISO (synonym: ISO_8859_15_Encoding) .TP KOI8REncoding - .RE ' .Sp .TP 5 .BR \-\-encoding\-text "=\fItext\fR, " \-E " \fItext" Use the encoding in the .I text argument, which must be formatted as a .M dvips 1 encoding. One of .B \-\-encoding and .B \-\-encoding\-text must be supplied. ' .Sp .TP 5 .BR \-\-name "=\fIname\fR, " \-n " \fIname" Set the output font's PostScript name to .IR name . The default is the input font name followed by the encoding's name. ' .Sp .TP 5 .BR \-\-full-name "=\fIname\fR, " \-N " \fIname" Set the output font's FullName to .IR name . The default is the input FullName followed by the encoding's name. ' .Sp .TP 5 .BR \-\-output "=\fIfile\fR, " \-o " \fIfile" Send output to .I file instead of standard output. ' .Sp .TP 5 .BR \-\-pfb ", " \-b Output a PFB font. This is the default. ' .Sp .TP 5 .BR \-\-pfa ", " \-a Output a PFA font. ' .Sp .TP 5 .BR \-h ", " \-\-help Print usage information and exit. ' .Sp .TP 5 .BR \-\-version Print the version number and some short non-warranty information and exit. .PD ' .SH "RETURN VALUES" .B T1reencode exits with value 0 if a re-encoded font was successfully generated, and 1 otherwise. ' .SH "NOTES" .LP .B T1reencode should be used only in special situations. It's generally much better to use PostScript commands to re-encode a font; for instance, executing the PostScript commands to generate two differently-encoded versions of a single font will take up much less memory than loading two .BR t1reencode d fonts. ' .SH "EXAMPLES" .PP This command re-encodes Frutiger Roman in the ISO Latin\~1 encoding. The new font will have the PostScript name Frutiger-RomanISOLatin1Encoding. .Sp .nf \fBt1reencode\fR \fB\-e\fR ISOLatin1Encoding FrutiRom.pfb \e \fB\-o\fR FrutiRomISOL1.pfb .fi .Sp This series of commands, which use .M cfftot1 1 and .M otftotfm 1 as well as .B t1reencode itself, generate a version of Warnock Pro Regular with old-style figures in the slots for numbers (because of .BR otftotfm 's .BR \-f onum option). The new font will be called WarnockPro-RegularOsF. .Sp .nf \fBotftotfm\fR \fB\-f\fRonum WarnockPro-Regular.otf \e \fB\-\-output\-encoding\fR /tmp/osf.enc \fBcfftot1\fR WarnockPro-Regular.otf | \fBt1reencode\fR \fB\-e\fR /tmp/osf.enc \e \fB\-n\fR WarnockPro-RegularOsF \fB\-N\fR "Warnock Pro Regular OsF" \e \fB\-o\fR WarnoProRegOsF.pfb .fi ' .SH "SEE ALSO" .LP .IR "Adobe Type 1 Font Format" , .M dvips 1 , .M cfftot1 1 , .M otftotfm 1 ' .SH AUTHOR Eddie Kohler (ekohler@gmail.com) lcdf-typetools-2.108/t1reencode/Makefile.in0000644000175000017500000005215613423376574015542 00000000000000# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : bin_PROGRAMS = t1reencode$(EXEEXT) subdir = t1reencode ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/lcdf-typetools.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/autoconf.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" PROGRAMS = $(bin_PROGRAMS) am_t1reencode_OBJECTS = t1reencode.$(OBJEXT) util.$(OBJEXT) t1reencode_OBJECTS = $(am_t1reencode_OBJECTS) t1reencode_DEPENDENCIES = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(t1reencode_SOURCES) DIST_SOURCES = $(t1reencode_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KPATHSEA_DEPEND = @KPATHSEA_DEPEND@ KPATHSEA_INCLUDES = @KPATHSEA_INCLUDES@ KPATHSEA_LIBS = @KPATHSEA_LIBS@ KPATHSEA_RULE = @KPATHSEA_RULE@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SELECTED_SUBDIRS = @SELECTED_SUBDIRS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TEMPLATE_OBJS = @TEMPLATE_OBJS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ encdir = @encdir@ exec_prefix = @exec_prefix@ glyphlistdir = @glyphlistdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign man_MANS = t1reencode.1 t1reencode_SOURCES = t1reencode.cc \ util.cc util.hh t1reencode_LDADD = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_CPPFLAGS = -I$(srcdir)/../include CLEANFILES = @TEMPLATE_OBJS@ EXTRA_DIST = t1reencode.1 all: all-am .SUFFIXES: .SUFFIXES: .cc .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign t1reencode/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign t1reencode/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) t1reencode$(EXEEXT): $(t1reencode_OBJECTS) $(t1reencode_DEPENDENCIES) $(EXTRA_t1reencode_DEPENDENCIES) @rm -f t1reencode$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(t1reencode_OBJECTS) $(t1reencode_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1reencode.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-man uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-binPROGRAMS install-data install-data-am \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-man1 install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-binPROGRAMS uninstall-man uninstall-man1 .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lcdf-typetools-2.108/t1reencode/Makefile.am0000664000175000017500000000053512732752520015514 00000000000000## Process this file with automake to produce Makefile.in AUTOMAKE_OPTIONS = foreign bin_PROGRAMS = t1reencode man_MANS = t1reencode.1 t1reencode_SOURCES = t1reencode.cc \ util.cc util.hh t1reencode_LDADD = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_CPPFLAGS = -I$(srcdir)/../include CLEANFILES = @TEMPLATE_OBJS@ EXTRA_DIST = t1reencode.1 lcdf-typetools-2.108/install-sh0000755000175000017500000003452312732752553013443 00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2013-12-25.23; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. tab=' ' nl=' ' IFS=" $tab$nl" # Set DOITPROG to "echo" to test this script. doit=${DOITPROG-} doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) is_target_a_directory=always dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done # We allow the use of options -d and -T together, by making -d # take the precedence; this is for compatibility with GNU install. if test -n "$dir_arg"; then if test -n "$dst_arg"; then echo "$0: target directory not allowed when installing a directory." >&2 exit 1 fi fi if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then if test $# -gt 1 || test "$is_target_a_directory" = always; then if test ! -d "$dst_arg"; then echo "$0: $dst_arg: Is not a directory." >&2 exit 1 fi fi fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac oIFS=$IFS IFS=/ set -f set fnord $dstdir shift set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: lcdf-typetools-2.108/NEWS.md0000644000175000017500000010215713423376542012532 00000000000000LCDF Typetools NEWS =================== ## Version 2.108 – 27.Jan.2019 * Handle more fonts. * `otftotfm -a`: Run `updmap-sys` by default. ## Version 2.107 – 22.Feb.2018 * Some corrections to output of `--math-spacing`. * Reduce undefined behavior. * Handle some incorrect fonts more gracefully. ## Version 2.106 – 21.Jun.2016 * Minor updates, mostly involving licensing of Adobe code and data. ## Version 2.105 – 15.Sep.2015 * Several crash fixes. * `otfinfo -g`: Print all Unicode mappings for a glyph. * t1lint: Support counter control hints. * Thanks to Github issue contributors. ## Version 2.104 – 7.Jul.2014 * Fix a nit with format-1 chaining context substitutions. ## Version 2.103 – 6.Jul.2014 * otftotfm: Address a problem experienced by Bob Tennent where a ligature setting wasn't included in the output VPL. ## Version 2.102 – 4.Jul.2014 * otftotfm: Fix the construction of multi-character secondary replacements; they were given enormous widths. Reported by Wydra Dennis. ## Version 2.101 – 16.Jun.2014 * otftotfm: Handle fonts with unexpected transformation matrices, such as CFF fonts with 2048 units per em. * otftotfm: Add `--x-height` option. * otftotfm: Handle more TrueType fonts by fixing otftotfm bugs and compensating for some TTF bugs. * Thanks to Bob Tennent and Marc Penninga. ## Version 2.100 – 8.Jan.2014 * otftotfm: On some fonts, ligature handling could enter an infinite loop. Fix this. Reported by Marc Penninga and Bob Tennent. * Fix updmap runs. * Build updates for C++11 and other compilers. ## Version 2.99 – 13.Aug.2013 * cfftot1: Correct bug that rarely corrupted Type 1 output fonts. Reported by Sebastian Schubert. ## Version 2.98 – 10.Apr.2013 * Fix alignment bug that corrupted output fonts on some platforms (MIPS especially). Reported by Norbert Preining. ## Version 2.97 – 25.Oct.2012 * Same. ## Version 2.96 – 25.Oct.2012 * Build improvements inspired by Peter Breitenlohner. ## Version 2.95 – 21.Sep.2012 * Fix cfftot1: Don't crash on problematic fonts. Bob Tennent report. ## Version 2.94 – 3.Aug.2012 * More compilation updates. ## Version 2.93 – 23.Jul.2012 * Correct compilation problem reported by Dennis Veatch. * Update OpenType feature, script, and language lists, and some other nits. ## Version 2.92 – 14.Aug.2011 * Correct horrible x86-64 byte-order issue. Bug reported by Michael Ummels. ## Version 2.91 – 13.Jun.2011 * Correct some compilation problems on unusual systems reported by Vladimir Volovich. ## Version 2.90 – 3.Jun.2011 * Correct crash on glyph names that start with a dot. Marc van Dongen report. ## Version 2.89 – 2.Jun.2011 * Better handle combinations of fonts and options that would create so many substitutions that otftotfm would run out of memory. Marc van Dongen report. * Thanks to Peter Breitenlohner. ## Version 2.88 – 8.Mar.2011 * Warning reduction. ## Version 2.87 – 27.Jan.2011 * Avoid double-free error in t1testpage. Reported by Kurt Pfeifle. ## Version 2.86 – 16.Dec.2010 * Support version 4 of the OpenType OS/2 table. Reported by Thomas Zumbrunn. ## Version 2.85 – 26.Sep.2010 * Correct otftotfm bug with glyphlist.txt mappings like I_J. ## Version 2.84 – 15.Sep.2010 * otftotfm: Avoid crashes on very large fonts and other odd situations. Bugs reported by Martin Schröder. * Include new Unicode mappings for glyph names from MSAM and MSBM. * Bug fixes to texglyphlist.txt Unicode mappings. Thanks to Clea F. Rees. ## Version 2.83 – 23.Apr.2010 * otftotfm: If `-fkern` loads no GPOS lookups, apply the TTF kern table (if it exists). This should use the TTF kern table strictly more often than the previous version. Based on draft changes to the OpenType spec. * Update with changes from TeX Live. Thanks to Peter Breitenlohner. ## Version 2.82 – 19.Jan.2010 * otftotfm: Correctly handle multiply-encoded glyphs (for example, if "j" ends up encoded in more than one slot, apply the j => j.smcp feature to both occurrences). Reported by Michael Ummels. ## Version 2.81 – 7.Jan.2010 * otftotfm: Fix "em" and "ex" measurements (QUAD and XHEIGHT font dimensions) for TrueType fonts. Problem reported by Nico Schlömer. * otftotfm: Add `--type42` option. ## Version 2.80 – 10.Nov.2009 * otftotfm: Add `--fixed-width`, `--proportional-width`, and `--italic-angle` options. Requested by Karl Berry. ## Version 2.79 – 12.Jun.2009 * otftotfm: Use TrueType "kern" tables to satisfy the `-fkern` feature if GPOS information isn't available. Requested by Nico Schlömer. * ttftotype42: Split very large non-glyf tables, as well as very large glyf tables. Requested by Mark DeVries. * otfinfo: The `-T` option dumps a table's contents to standard out. * Introduce and use a consistent hashcode_t type. Reported by Karl Berry. ## Version 2.78 – 6.Apr.2009 * t1lint: Report warnings when a font charstring command has too many arguments. Requested by Han The Thanh. ## Version 2.77 – 6.Apr.2009 * Font library changes: correctly implement binary search in a couple places -- unexpected sizes could lead to overflow and bad behavior. Reported by Mark DeVries for ttftotype42 and CharisSILR. ## Version 2.76 – 27.Mar.2009 * mmpfb: Ensure all output subroutines end in the "return" command; some type 1 processors treat a subroutine ending in "endchar" as an error. Reported by Melissa O'Neill. * mmpfb, cfftot1: Ensure that stem3 hints (hstem3, vstem3) meet the necessary constraints, even despite rounding. * t1lint: Add checks for some more problems, such as subroutines that do not end in "return." Reported/requested by Melissa O'Neill and Han The Thanh. ## Version 2.75 – 22.Feb.2009 * Report a helpful warning if automatic mode is specified to a version without kpathsea support. Question from Keith Briggs. ## Version 2.74 – 16.Feb.2009 * Correctly detect . Problem reported by C.M. Connelly. ## Version 2.73 – 15.Feb.2009 * cfftot1 bug fix: Avoid introducing stray "rmoveto" commands and attendant visual artifacts into the output. The problem was caused by some coordinate system confusion. Reported by John Owens, who had tried to convert Inconsolata. ## Version 2.72 – 27.Oct.2008 * t1rawafm: Add missing newlines; thanks, Michael Zedler. * otftotfm: Understand "UniXXXX" glyph names. They're not standard, but it's pretty obvious what they imply. Reported by Vasile Gaburici. ## Version 2.71 – 8.Aug.2008 * otftotfm: Correctly install TrueType files when `--force`. Reported by Vasile Gaburici. ## Version 2.70 – 8.Aug.2008 * Add new t1rawafm program, which generates a "raw" (kernless and ligatureless) AFM file given a font file (PFB/PFA). * otftotfm: When installing, `--automatic` ignores files existing in the current directory. Confusion reported by Vasile Gaburici. * Type 1 parsing: Parse fonts with rare encoding formats, such as bases other than 10. ## Version 2.69 – 5.May.2008 * Mini portability fix for problem reported by Vladimir Volovich. ## Version 2.68 – 2.May.2008 * otftotfm: Tweak the ligature sorting algorithm. Prefer lowercase ligatures to mixed-case and uppercase ligatures; prefer the conventional f-ligatures to all others. Reported by Ulrich Dirr. ## Version 2.67 – 25.Apr.2008 * otftotfm: Improve font name construction for base fonts. Reported by Ulrich Dirr. ## Version 2.66 – 3.Aug.2007 * otftotfm: TrueType fonts had inappropriately large kerning pairs; fixed. Reported by Marc Penninga. ## Version 2.65 – 22.Jul.2007 * t1testpage: Fix bug triggered by fonts with empty encoding slots. Reported by Michael Zedler. ## Version 2.64 – 25.Jun.2007 * Handle Extension format GPOS and GSUB lookup tables, used for very large fonts. Reported by Marc Penninga. * cfftot1, t1lint: Correct misunderstanding of the Flex spec: there MUST be an rmoveto in between any two Flex subroutines, even if that rmoveto doesn't move anywhere. (Question: Are hmoveto/vmoveto acceptable? Adobe Reader seems to think so.) Reported by John Owens with respect to Caslon-Antique. ## Version 2.63 – 12.Jun.2007 * Correctly handle fonts with 4-byte character code cmap tables. Reported by Alexey Vikhlinin. ## Version 2.62 – 11.Apr.2007 * t1dotlessj: Do not use the same UniqueID as the input font. Inspired by Reinhard Kotucha. * otftotfm: Generate a map line even if there was a missing character in some UNICODING. Reported by Andreas Bühmann. ## Version 2.61 – 25.Mar.2007 * otftotfm: Automatically reduce DESIGNUNITS and try again if a font has humungocharacters that overflow PL files' limited range of allowed real numbers. Reported by John Owens. ## Version 2.60 – 27.Feb.2007 * otftotfm: Rearrange order of virtual fonts so most-frequently-used font comes in position 0. Requested by Michael Zedler. * otftotfm: Apply letterspacing to "dotlessj". Maybe finally this is right. ## Version 2.59 – 23.Feb.2007 * otftotfm: %POSITION commands don't add glyphs to the encoding. Requested by Achim Blumensath. ## Version 2.58 – 22.Feb.2007 * otftotfm: More of the same (with respect to "Germandbls"), again reported by Michael Zedler. ## Version 2.57 – 21.Feb.2007 * otftotfm: More of the same: "emptyslot" glyphs don't generate spurious base fonts. Again reported by Michael Zedler. ## Version 2.56 – 13.Feb.2007 * otftotfm: Guess what? ## Version 2.55 – 13.Feb.2007 * otftotfm: Finally fix (?) letterspacing for simulated characters. ## Version 2.54 – 12.Feb.2007 * otftotfm: Include letterspacing for simulated characters. Bug reported by Michael Zedler. ## Version 2.53 – 11.Feb.2007 * otftotfm: Positionings and letterspacing apply even with `--base-encodings`. Bug reported by Michael Zedler. ## Version 2.52 – 6.Feb.2007 * otftotfm: `--base-encodings` fixes for dotless-J fonts. ## Version 2.51 – 6.Feb.2007 * otftotfm: Some `--base-encodings` fixes. ## Version 2.50 – 6.Feb.2007 * otftotfm: Add `--base-encodings` option. Requested by Michael Zedler. ## Version 2.49 – 11.Jan.2007 * Report certain types of invalid 'size' features that occasionally occur in old fonts. Thanks to John Owens and Read Roberts. ## Version 2.48 – 11.Dec.2006 * Translate font names into UTF-8 encoding. Reported by John Owens. ## Version 2.47 – 10.Dec.2006 * otfinfo: Add new names, such as "Preferred Family", to `otfinfo -i` output. Requested by John Owens. ## Version 2.46 – 29.Oct.2006 * otftotfm: Base metrics files now reflect the actual base font metrics more accurately (rather than containing virtual-font-only metrics information, such as letterspacing). This should make it easier to tell, using "diff", whether two base metrics files contain the same data. * otftotfm: `--no-type1` does not affect dotless-j font generation; use `--no-dotlessj` for that (Michael Zedler). * otftotfm: Don't generate virtual fonts unless you have to (Michael Zedler). ## Version 2.45 – 17.Sep.2006 * Include new ttftotype42 program. ## Version 2.44 – 16.Sep.2006 * otfinfo/otftotfm: Support new fonts whose 'size' features are defined correctly. Thanks to Read Roberts for defining the compatibility check. ## Version 2.43 – 22.Aug.2006 * otftotfm: Check for availability of kpse_opentype_format. Bug reported by Carsten Luckmann. ## Version 2.42 – 22.Aug.2006 * otftotfm: Any `--altselector-char` is actually encoded, so you can use it as a regular character as well as an altselector. Suggested by Carsten Luckmann. ## Version 2.41 – 12.Aug.2006 * otftotfm: Some TrueType fixes. Problems reported by Michael Zedler. ## Version 2.40 – 1.Aug.2006 * otftotfm: Initial support for TrueType-flavored OpenType fonts. Inspired because John Owens is working with Microsoft's Calibri et al. ## Version 2.39 – 11.Jul.2006 * cfftot1: Unify some subroutines previously missed, for slightly smaller output. Reported by Michael Zedler. ## Version 2.38 – 8.May.2006 * otfinfo: Add `--info` option. Requested by John Owens. ## Version 2.37 – 25.Jan.2006 * otftotfm: Add 'ringfitted'. Requested by Michael Zedler. Required bug fix. ## Version 2.36 – 9.Nov.2005 * otfinfo: Add `-a/--family` option. Based on patch from Ottavio G. Rizzo. * otftotfm: Fix bug where `-q` would inhibit map line output, reported by Achim Blumensath. ## Version 2.35 – 3.Oct.2005 * otftotfm: Allow `--ligkern "T h=:T_h"` (note lack of spaces around '=:'). Inspired by Michael Saunders. * otftotfm: Split TeX extensions out from 'glyphlist.txt' into 'texglyphlist.txt', leaving 'glyphlist.txt' exactly as distributed by Adobe. Otftotfm reads both files. Requested by Werner Lemberg. * otftotfm: Add `% WARNMISSING` and `--warn-missing`, so that missing characters result in blots and cause warnings when processed by dvips. Requested by Michael Zedler. * otfinfo: Add `-v/--font-version` option and document `-t/--tables` option. * t1reencode: Add many more standard encodings to t1reencode, and fix existing ones. Patch from Peter Betzler. ## Version 2.34 – 11.Jun.2005 * otftotfm: Search for 'glyphlist.txt' using kpathsea, and set kpathsea program name to 'lcdftools'. Requested by Karl Berry. ## Version 2.33 – 3.Jun.2005 * otftotfm: Include more secondary replacements, including double-bar, centered asterisk, per-ten-thousand, and so forth. Patch from Michael Zedler. * otftotfm: Add `% POSITION` and `--position`. Requested by Michael Zedler. ## Version 2.32 – 31.May.2005 * otftotfm: Report correct dimensions for characters only in the base encoding. Reported by Michael Zedler. ## Version 2.31 – 30.May.2005 * otftotfm: Fix crash tickled by constructed characters, reported by Michael Zedler. * Compilation fixes suggested by Nelson H.F. Beebe. ## Version 2.30 – 8.May.2005 * otftotfm: Add support for 'dblbracketleft' and 'dblbracketright'. Secondary replacement can add characters to the font. * otftotfm: Ligkern commands 'A {5} B' and 'A {L} B' can coexist, leading to a 5-character kern and no ligature. Requested by Michael Zedler. ## Version 2.29 – 7.May.2005 * otftotfm: Fix crash reported by Ryuji Suzuki. * otftotfm: Add support for 'capitalcompwordmark' and 'ascendercompwordmark', requested by Michael Zedler. * otftotfm: Use OpenType OS/2 table to determine x-height, if available. ## Version 2.28 – 25.Apr.2005 * otftotfm: `--math-spacing` doesn't set italic corrections to 0. Thanks to Achim Blumensath. ## Version 2.27 – 24.Apr.2005 * otftotfm: Add support for setting kerns: `--ligkern "A {5} B"`. Thanks to Achim Blumensath for a patch. * otftotfm: Add preliminary support for heuristically-derived math accent positions via a 'skewchar' argument to `--math-spacing`. Thanks again to Achim Blumensath. ## Version 2.26 – 2.Apr.2005 * otftotfm: Support more kinds of substitution. * otftotfm: Support old-style and new-style chaining context substitutions using Adobe's procedure. Older fonts had erroneous substitutions because of a software error; newer fonts don't. * otftotfm: Fix crash tickled by newer versions of MinionPro and other fonts, reported by Michael Zedler and Oliver M. Haynold. ## Version 2.25 – 10.Mar.2005 * otftotfm: Ignore unencoded default ligkerns (don't try to encode their characters). Reported by Michael Zedler. ## Version 2.24 – 10.Mar.2005 * otftotfm: Fix assertion failure introduced in 2.23. ## Version 2.23 – 8.Mar.2005 * otftotfm: Fix bug present since 2.20 where, for example, `--unicoding "germandbls =: SSsmall"` was ignored in favor of a named 'germandbls' character. Reported by Michael Zedler. ## Version 2.22 – 2.Mar.2005 * otftotfm: Include default ligatures unless `--no-default-ligkern` is given. This seems cleaner than the previous semantics (which included the default ligatures unless there were ligatures in the encoding and/or the command line), but it is incompatible. Inspired by question from Christopher Swingely. ## Version 2.21 – 16.Feb.2005 * otftotfm: Base fonts include no kerns or ligatures. Requested by Michael Zedler. * cfftot1: Correctly handle default values for CFF fonts, so that, for example, isFixedPitch is defined to false even when the font doesn't mention it. Requested by Huver. ## Version 2.20 – 9.Feb.2005 * otftotfm: Add `--space-factor` and `--math-spacing` options, based on patches from Achim Blumensath. * otftotfm: Improve handling of explicit `--ligkern` ligatures: they override default ligatures, and any characters mentioned are shoehorned into the encoding. Catalyzed by Michael Zedler. ## Version 2.19 – 4.Feb.2005 * otftotfm: Add `--subs-filter`, `--include-subs`, `--exclude-subs`, and `--clear-subs` options (inspired by patch from Achim Blumensath). * otftotfm: Update documentation and behavior for newer teTeX installations. For instance, run the system `updmap` by default (unless you give the `--no-updmap` option). This makes automatic mode much easier to set up. * otftotfm: Output pltotf and vptovf messages to standard error (Achim Blumensath). * otftotfm: Protect arguments given to the shell (Achim Blumensath). * otfinfo: Add `-g` option to query all glyphs in a font. ## Version 2.18 – 26.Jan.2005 * otftotfm: Fix bug that could cause infinite loops on FreeBSD machines. ## Version 2.17 – 4.Jan.2005 * Add t1reencode program. Requested by Ralph Aichinger. * otftotfm: Add `--output-encoding` option. * t1lint: Check that UniqueID and XUID values are in range. ## Version 2.16 – 19.Nov.2004 * `--include-alternates` and `--exclude-alternates` options only apply to features that appear later in the options list. * Fix bug where not all `--altselector-feature` features would be used. Problem reported by Emil Lohse. * Add `--clear-alternates` option. ## Version 2.15 – 21.Sep.2004 * AIX compile fixes. Reported by Vladimir Volovich. * Include RPM .spec file, provided by C.M. Connelly. ## Version 2.14 – 16.Sep.2004 * Use AM_MAINTAINER_MODE. Suggested by Karl Berry. * IRIX compile fixes. Reported by Olaf Weber. ## Version 2.13 – 12.Sep.2004 * otftotfm: Check $TEXMF if $VARTEXMF has no writable directory. Reported by Simon Patarin. * Add `--enable-selfauto-loc` configuration option, enabled by default, to help otftotfm run with TeX configuration files that use SELFAUTODIR and related variables. Suggested by Thomas Esser; mechanism from dvipng. ## Version 2.12 – 19.Aug.2004 * Catch bug that would affect otftotfm on 64-bit machines. ## Version 2.11 – 18.Aug.2004 * otftotfm: Adjust TDS 1.1 support thanks to Olaf Weber. ## Version 2.10 – 18.Aug.2004 * otftotfm: Add preliminary support for the TeX Directory Structure 1.1 standard. * Bug fix that should let us compile on Cygwin. Problem reported by Christian Gudrian. ## Version 2.9 – 10.Aug.2004 * otftotfm: Add `--letter-feature` option, inspired by Michael Zedler. ## Version 2.8 – 5.Aug.2004 * otftotfm: Fix bug where missing GPOS or GSUB tables would cause an abort. Reported by Ryuji Suzuki. ## Version 2.7 – 3.Aug.2004 * otftotfm: Bug fix for obscure cases involving 'dotlessj' characters: the output VPL could contain a reference to "(SETCHAR X)", which is illegal. Reported by Marco Kuhlmann. ## Version 2.6 – 12.Jul.2004 * t1testpage adds preliminary support for font smoke proofs with `--smoke`. Requested by Karl Berry. * t1testpage adds `--glyph` option. ## Version 2.5 – 6.Jul.2004 * Support compilation with gcc-3.4.1. Reported by Thomas Esser. ## Version 2.4 – 30.Jun.2004 * cfftot1: Fix off-by-one bug where the encoding of the last encoded character was ignored, reported by Detlev Droege. * otftotfm: Some internal changes; bugs are possible. ## Version 2.3 – 15.Jun.2004 * otftotfm: Add `--default-ligkern` and `--no-encoding-commands` options, to address problem with "t1.enc" reported by Ulrich Dirr. * otftotfm documentation updates. ## Version 2.2 – 8.May.2004 * otftotfm: 't1dotlessj' errors don't prevent 'psfonts.map' from being updated. Reported by Stephen Moye. * t1dotlessj: Report different kinds of errors with different exit statuses. ## Version 2.1 – 5.Apr.2004 * otftotfm: Warn if no encoding specified. Requested by Zsolt Kiraly. * otftotfm: Improve documentation, particularly by adding example run with ".fd" file. ## Version 2.0 – 21.Mar.2004 * mmpfb, t1dotlessj, t1lint, t1testpage: On Windows, add _O_BINARY flag when appropriate. Reported by Fabrice Popineau. ## Version 1.99 – 24.Feb.2004 * otftotfm: Fix overfull encoding bug that could cause an assertion failure, reported by Adam Lindsay. * otftotfm: Speed improvement. ## Version 1.98 – 22.Feb.2004 * otftotfm: Add support for 'SSsmall' glyph. Einar Smith noted that the OpenType 'smcp' feature doesn't translate the sharp-S character to small-caps "SS" in most fonts. Now, add `--unicoding "germandbls =: SSsmall"` to get that behavior. * otftotfm: Compilation fix for problem reported by Nelson H.F. Beebe. ## Version 1.97 – 6.Feb.2004 * cfftot1: Fix bug in handling fonts with supplemental encodings. Problem reported by Eike . ## Version 1.96 – 11.Jan.2004 * otftotfm: Handle alternate characters like 'Q.alt' in the input encoding: map them to the actual alternate glyph, rather than to the base Unicode value ('Q'). Reported by Ulrich Dirr. ## Version 1.95 – 3.Jan.2004 * otftotfm: Add automatic support for t1dotlessj. If the desired encoding has a 'dotlessj' character, and the input font doesn't, then otftotfm will run 't1dotlessj', create a dotless-J font, and include it using virtual fonts. * otftotfm: Avoid warnings about bad "(STOP)" commands in pltotf (introduced by the `--min-kern` facility). ## Version 1.91 – 31.Dec.2003 * mmpfb, t1dotlessj: Fix sidebearing problems. ## Version 1.90 – 29.Dec.2003 * mmpfb: Fix behavior with Adobe Jenson and other fonts with intermediate masters, and `--minimize` output, which had been broken since 1.65. * Add t1dotlessj program. ## Version 1.88 – 23.Dec.2003 * otfinfo: Change coding to be friendlier to older C++ compilers. Requested by Ulrich Dirr. ## Version 1.87 – 22.Dec.2003 * otftotfm: Fix `--extend` bug reported by Ulrich Dirr (the expansion factor was formerly applied to character heights and depths, not widths). ## Version 1.86 – 19.Dec.2003 * otftotfm: Change where `--base` is added to support pdftex: If the font name is "WarnoPro+10", the base font name is "WarnoPro--base+10". Reported by Ulrich Dirr. ## Version 1.85 – 10.Dec.2003 * otftotfm: Add `--altselector-feature` option, so you can specify the features activated by `--altselector-char`. Defaults to salt and dlig. * otftotfm: Fix intermittent hang. ## Version 1.80 – 4.Dec.2003 * otftotfm: Add `--altselector-char` option, and `--include-alternates` and `--exclude-alternates` options. These options support access to alternate characters through ligatures, using a mechanism originally planned by Sivan Toledo ("Exploiting Rich Fonts", TUGboat 21(2), 2000). Requested by Martin Budaj. * Add default encoding for 'SS' character (same as 'Germandbls'). Reported by Ulrich Dirr. ## Version 1.75 – 3.Dec.2003 * cfftot1: Handle the case when 'hintmask' is the first operator in a Type 2 charstring. Reported by Tom Kacvinsky. ## Version 1.70 – 1.Dec.2003 * otftotfm: Add `--min-kern` option requested by Ulrich Dirr. * mmafm: Add `--min-kern` as a preferred synonym for `--kern-precision`. ## Version 1.67 – 29.Nov.2003 * otftotfm: Don't run off the end of an array. Bug reported and patch provided by Akira Kakuto. ## Version 1.66 – 24.Nov.2003 * cfftot1: Don't generate "currentfile eexec" twice. Bug reported by Adam Lindsay. ## Version 1.65 – 24.Nov.2003 * otftotfm: Include default ligatures if user does not specify ligatures. Requested by Adam Lindsay. * otftotfm: Generated VPL includes FONTDSIZE when referring to base. Bug reported by Adam Lindsay. * Preliminary support for CID-keyed OpenType fonts. ## Version 1.60 – 7.Oct.2003 * cfftot1: Support fonts using the 'seac' operator. Requested by Ralf Koenig. ## Version 1.52 – 4.Sep.2003 * otftotfm: Add `--design-size` option requested by Johannes Kuester. * t1testpage: Fix `--help` and add manual page at C.M. Connelly's request. ## Version 1.51 – 2.Sep.2003 * otftotfm: Generated TFM and PL files have DESIGNSIZE set to the font's actual design size, as read from the 'size' feature. Requested by Johannes Kuester. ## Version 1.50 – 26.Aug.2003 * Minor compilation fix; problem reported by Nelson H.F. Beebe. ## Version 1.50b4 – 26.Aug.2003 * otfinfo: Minor compilation fix from Tom Kacvinsky. ## Version 1.50b3 – 25.Aug.2003 * cfftot1: Emit UniqueID as an integer. Reported by Tom Kacvinsky. * otftotfm: `--without-kpathsea` fix. Patch provided by Adam Lindsay. * More compilation fixes provided by Tom Kacvinsky. ## Version 1.50b2 – 24.Aug.2003 * otfinfo: New program, requested by Adam Lindsay. * otftotfm: The `--query-scripts` and `--query-features` options are no longer supported. Use `otfinfo -s` and `otfinfo -f` instead. * otftotfm: Fix crash reported by Adam Lindsay. * otftotfm: In automatic mode, after modifying a 'psfonts.map' file, run the script 'TEXMF/dvips/updmap' if present. * Compilation fixes for Solaris provided by Tom Kacvinsky and Nelson H.F. Beebe. ## Version 1.50b1 – 20.Aug.2003 * Integrate mminstance (the mmafm and mmpfb programs), and bump the version number to reflect this. ## Version 0.53 – 10.Aug.2003 * Fix problem with Type 1 output in `--without-kpathsea` reported by Adam Lindsay. * Fix crash on encodings containing 'emptyslot' reported by Marco Kuhlmann. ## Version 0.52 – 7.Aug.2003 * Attempt to fix some build problems reported by Nelson H.F. Beebe. ## Version 0.51 – 5.Aug.2003 * otftotfm: Fix crashes with small encodings and absent boundary characters. Reported by Bruce D'Arcus. * otftotfm: Add `--boundary-char` and `--kpathsea-debug` options. ## Version 0.50 – 4.Aug.2003 * otftotfm: Handle more complex substitutions, such as those required to support `-fordn` and `-ffrac`. * otftotfm: The output virtual and base fonts can have different "encodings" with overlapping encoding slots. This can make fonts more compact. * When assigning slots to introduced characters, otftotfm prefers characters introduced by earlier lookups. This follows the spirit of the OpenType specification, since early lookups in some ways "override" later ones. The previous scoring mechanism remains in force within each individual lookup. * otftotfm: Rewrite GsubEncoding to Metrics, changing its fundamental abstraction (to two-ligatures). Simpler and cleaner overall. * otftotfm TODO: Ligatures that apply to middle or right context (for example, the two substitutions "a b c d => a b c y" and "b c => x" should combine to "a b c d => a x y", but they won't yet). ## Version 0.19 – 30.Jul.2003 * otftotfm: Add support for 'emptyslot' UNICODINGs. Requested by Marco Kuhlmann. ## Version 0.18 – 9.Jul.2003 * Otftotfm will now synthesize characters for some T1 glyphs automatically, specifically 'cwm' (compound word mark), 'visualspace', and 'Germandbls'. Requested by Marco Kuhlmann. * The glyphlist.txt file contains Unicode mappings for character names found in the BlueSky Computer Modern math italic and symbol fonts. * It also contains fake Unicode mappings for the 'cwm', 'visualspace', and 'Germandbls' characters found in EC.enc. * otftotfm: Don't output a KRN between two characters if there exists a LIG for those two characters. ## Version 0.17 – 6.Jul.2003 * otftotfm: Ligatures removed with LIGKERN commands won't show up in the encoding. * Improve scoring heuristics by which otftotfm decides which characters are more important (for when there isn't enough encoding space for all new glyphs). ## Version 0.16 – 6.Jul.2003 * otftotfm: In automatic mode, store dvips files (encodings and psfonts.map) in 'TEXMF/dvips/VENDOR', rather than 'TEXMF/dvips'. Users of previous versions will probably want to move their 'TEXMF/dvips/a_*.enc' and 'TEXMF/dvips/lcdftools.map' files to a 'TEXMF/dvips/lcdftools/' directory, and run 'mktexlsr TEXMF'. * otftotfm: When there isn't enough encoding space for all new glyphs, prefer shorter ligatures made out of regular letters -- for instance, prefer f_j to f_f_j, and T_h to f_iacute. Requested by Bruce D'Arcus. * otftotfm: Add `--ligkern` and `--unicoding` options. * otftotfm: Add `--coding-scheme` option and `% CODINGSCHEME` encoding comment, to define the PL/TFM coding scheme for the font. Apparently fontinst actually looks at the coding scheme. Also, when you specify a coding scheme, set DESIGNUNITS to 1, again to satisfy fontinst. Requested by Marco Kuhlmann. * otftotfm: Remove virtual font 'N.vf' when installing a regular font 'N.tfm' in automatic mode. This reduces the risk that an old virtual font will screw up your installation. ## Version 0.15 – 4.Jul.2003 * otftotfm: Bug fix: Don't multiply apply substitutions and kerns from the same lookup. * otftotfm: Supports simple left-contextual substitutions, necessary for ExPontoPro's 'calt' (Contextual Alternates) feature. ## Version 0.14 – 2.Jul.2003 * otftotfm: Add `-L/--letterspacing` option at Bruce D'Arcus's request. * otftotfm: Hypothetically supports the contextual substitutions necessary for the 'init' (Initial Forms) feature. * otftotfm: When you make a virtual font named "foo", remove any entries for "foo" from VENDOR.map. ## Version 0.13 – 27.Jun.2003 * `--without-kpathsea` works. Problem reported by Adam Lindsay. ## Version 0.12 – 27.Jun.2003 * otftotfm: Better error messages when directories cannot be found. Reported by Bruce D'Arcus. ## Version 0.11 – 26.Jun.2003 * otftotfm: Handles the contextual substitutions necessary for 'cswh' (Contextual Swash) and 'fina' (Terminal Forms) features. ## Version 0.10 – 26.Jun.2003 * otftotfm: Update ls-R files for new encodings. ## Version 0.9 – 25.Jun.2003 * otftotfm: psfonts.map lines contain the file name only (no directories). Requested by Norbert Preining. * otftotfm: Properly report errors when encoding files can't be found. * Fix kpathsea searching and dependency problems reported by Bruce D'Arcus and Claire Connelly, among others. * Fix templates to allow compilation with GCC 2.95. ## Version 0.8 – 23.Jun.2003 * otftopl has been renamed to otftotfm. The new program takes different options. Automatic mode is particularly different, and TFM output is now the default. * otftotfm: Automatic mode now sticks files into a TeX Directory Structure hierarchy. This works well with many TeX installations. It also automatically translates OpenType fonts into Type 1 PostScript with cfftot1 (unless you configure with `--disable-cfftot1`), and modifies a psfonts.map file for each font. See the manual page for more information. * otftotfm: Generates virtual fonts when required to support glyph positioning features. (`-f cpsp` is one example.) * otftotfm: Warns when a feature could not be completely implemented. * otftotfm: Add `--verbose` and `--no-create` options, among others (`--no-virtual`, `--map-file`, `--vendor`, `--typeface`, `--no-type1`...). * otftotfm: Encoding files are now named "a_SIGNATURE.enc", not "auto_SIGNATURE.enc". * The configure script now searches for the kpathsea library, since otftotfm's automatic mode depends on kpathsea. Provide `--without-kpathsea` to disable it. ## Version 0.7 – 13.Jun.2003 * cfftot1: Fix bug to handle MinionPro-Italic without crashing. ## Version 0.6 – 12.Jun.2003 * cfftot1: Fix definitions of Subrs entries 1 and 2; now fonts with flex hints will work. * cfftot1: Reduce noise generated by fonts with flex hints. * cfftot1: Generates valid character strings for characters whose first point is at the origin. (Previously, such charstrings wouldn't begin with a "moveto".) * otftopl: Support simple context substitutions and chained context substitutions. Required to support ACaslonPro-Italic's "swsh" feature. Reported by Adam Lindsay . * otftopl: Prefer `--query-features` and `--query-scripts` to `--print-features` and `--print-scripts`. * otftopl: Better warnings and error messages for bad LIGKERN/UNICODING commands in encoding files, and when there isn't enough room in an encoding for ligature glyphs. * t1lint: Reads stdin if no filenames supplied on the command line. ## Version 0.5 – 5.Jun.2003 * Template reorganization so the typetools compile with GCC 3.3. ## Version 0.4 – 3.Jun.2003 * otftopl: Added `--slant` and `--extend` options. * otftopl's generated encodings have slightly different form, and are thus friendlier to ps2pk's bad parser. ## Version 0.3 – 3.Jun.2003 * Fixed bug: cfftot1 produced invalid results for fonts with encodings other than StandardEncoding, due to a misbehavior in the way Type 1 fonts were stored. Reported by Vladimir Volovich . ## Version 0.2 – 3.Jun.2003 * Fix CFF parsing bugs and configure errors reported by Vladimir Volovich . ## Version 0.1 – 2.Jun.2003 * Initial release. * See also the ONEWS file for older news about mmafm and mmpfb. lcdf-typetools-2.108/t1rawafm/0000755000175000017500000000000013423377073013230 500000000000000lcdf-typetools-2.108/t1rawafm/t1rawafm.10000644000175000017500000000234013423376706014755 00000000000000.ds V 2.108 .de M .BR "\\$1" "(\\$2)\\$3" .. .de Sp .if n .sp .if t .sp 0.4 .. .TH T1RAWAFM 1 "LCDF Typetools" "Version \*V" .SH NAME t1rawafm \- produce raw AFM metrics from a PostScript Type 1 font .SH SYNOPSIS \fBt1rawafm\fR \%[OPTIONS...] [\fIfont\fR [\fIoutputfile\fR]] .SH DESCRIPTION .BR T1rawafm generates an AFM file with the information available in a PostScript Type\~1 font. The AFM file will lack kerns, ligature information, and composite characters, but is otherwise usable. The AFM file is written to the standard output (but see the .B \-\-output option). If no input font file is supplied, .B t1rawafm reads a PFA or PFB font from the standard input. ' .SH OPTIONS .PD 0 .TP 5 .BR \-\-output "=\fIfile\fR, " \-o " \fIfile" Send output to .I file instead of standard output. ' .Sp .TP 5 .BR \-h ", " \-\-help Print usage information and exit. ' .Sp .TP 5 .BR \-\-version Print the version number and some short non-warranty information and exit. .PD ' .SH "RETURN VALUES" .B T1rawafm exits with value 0 if an AFM metrics file was successfully generated, and 1 otherwise. ' .SH "SEE ALSO" .LP .IR "Adobe Type 1 Font Format" , .IR "Adobe Font Metrics File Format Specification v4.1" ' .SH AUTHOR Eddie Kohler (ekohler@gmail.com) lcdf-typetools-2.108/t1rawafm/t1rawafm.cc0000644000175000017500000002530213423375330015175 00000000000000/* t1rawafm.cc -- driver for generating a raw AFM file from a font * * Copyright (c) 2008-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_CTIME # include #endif #if defined(_MSDOS) || defined(_WIN32) # include # include #endif using namespace Efont; #define VERSION_OPT 301 #define HELP_OPT 302 #define OUTPUT_OPT 303 #define SMOKE_OPT 305 const Clp_Option options[] = { { "help", 'h', HELP_OPT, 0, 0 }, { "output", 'o', OUTPUT_OPT, Clp_ValString, 0 }, { "version", 0, VERSION_OPT, 0, 0 }, }; static const char *program_name; static PermString::Initializer initializer; void usage_error(ErrorHandler *errh, const char *error_message, ...) { va_list val; va_start(val, error_message); if (!error_message) errh->message("Usage: %s [OPTION]... [FONT [OUTPUT]]", program_name); else errh->xmessage(ErrorHandler::e_error, error_message, val); errh->message("Type %s --help for more information.", program_name); exit(1); } void usage() { FileErrorHandler uerrh(stdout); uerrh.message("\ % generates a raw (kernless and ligatureless) AFM file corresponding\n\ to the specified Type 1 font file and writes it to the standard output.\n\ \n\ Usage: %s [OPTION]... [FONT [OUTPUT]]\n\ \n\ FONT is the name of a PFA or PFB font file. If omitted, t1rawafm will read a\n\ font file from the standard input.\n\ \n\ Options:\n\ -o, --output=FILE Write output to FILE instead of standard output.\n\ -h, --help Print this message and exit.\n\ --version Print version number and exit.\n\ \n\ Report bugs to .\n", program_name); } // MAIN static Type1Font *font; static void do_file(const char *filename, PsresDatabase *psres, ErrorHandler *errh) { FILE *f; if (!filename || strcmp(filename, "-") == 0) { f = stdin; filename = ""; #if defined(_MSDOS) || defined(_WIN32) _setmode(_fileno(f), _O_BINARY); #endif } else f = fopen(filename, "rb"); if (!f) { // check for PostScript name Filename fn = psres->filename_value("FontOutline", filename); f = fn.open_read(); } if (!f) errh->fatal("%s: %s", filename, strerror(errno)); Type1Reader *reader; int c = getc(f); ungetc(c, f); if (c == EOF) errh->fatal("%s: empty file", filename); if (c == 128) reader = new Type1PFBReader(f); else reader = new Type1PFAReader(f); font = new Type1Font(*reader); if (!font->ok()) errh->fatal("%s: not a Type 1 font", filename); delete reader; } /***** * MAIN PROGRAM **/ struct fontinfo_t { const char *afm_name; int dict; const char *dict_name; bool as_string; }; static const fontinfo_t fontinfo_strings[] = { { "Version", Type1Font::dFI, "version", true }, { "Notice", Type1Font::dFI, "Notice", true }, { "FullName", Type1Font::dFI, "FullName", true }, { "FamilyName", Type1Font::dFI, "FamilyName", true }, { "Weight", Type1Font::dFI, "Weight", true }, { "ItalicAngle", Type1Font::dFI, "ItalicAngle", false }, { "IsFixedPitch", Type1Font::dFI, "isFixedPitch", false }, { "UnderlinePosition", Type1Font::dFI, "UnderlinePosition", false }, { "UnderlineThickness", Type1Font::dFI, "UnderlineThickness", false } }; static String strip_newlines(const String &str) { StringAccum sa; const char *end = str.end(), *last = str.begin(); for (const char *s = str.begin(); s != end; ++s) if (*s == '\n' || *s == '\r' || *s == '\f' || *s == '\v') { sa.append(last, s); last = s + 1; } if (last == str.begin()) return str; else { sa.append(last, end); return sa.take_string(); } } static void write_char(FILE *outf, int c, PermString n, Type1Charstring *g, const Transform &font_transform, Type1Font *font) { double bb[4], wx; CharstringBounds::bounds(font_transform, CharstringContext(font, g), bb, wx); fprintf(outf, "C %d ; WX %d ; N %s ; B %d %d %d %d ;\n", c, (int) ceil(wx), n.c_str(), (int) floor(bb[0]), (int) floor(bb[1]), (int) ceil(bb[2]), (int) ceil(bb[3])); } static void write_afm(FILE *outf, Type1Font *font) { fprintf(outf, "StartFontMetrics 2.0\n\ Comment Generated by t1rawafm\n"); for (size_t i = 0; i < sizeof(fontinfo_strings) / sizeof(fontinfo_t); ++i) if (Type1Definition *t1d = font->dict(fontinfo_strings[i].dict, fontinfo_strings[i].dict_name)) { if (!fontinfo_strings[i].as_string) fprintf(outf, "%s %s\n", fontinfo_strings[i].afm_name, t1d->value().c_str()); else { String s; if (t1d->value_string(s)) fprintf(outf, "%s %s\n", fontinfo_strings[i].afm_name, strip_newlines(s).c_str()); } } Transform font_transform; { double font_matrix[6]; font->font_matrix(font_matrix); font_transform = Transform(font_matrix); font_transform.scale(1000); } double bb[4], wx; if (Type1Charstring *t1cs = font->glyph("H")) { CharstringBounds::bounds(font_transform, CharstringContext(font, t1cs), bb, wx); if (bb[3]) fprintf(outf, "CapHeight %d\n", (int) ceil(bb[3])); } if (Type1Charstring *t1cs = font->glyph("x")) { CharstringBounds::bounds(font_transform, CharstringContext(font, t1cs), bb, wx); if (bb[3]) fprintf(outf, "XHeight %d\n", (int) ceil(bb[3])); } if (Type1Charstring *t1cs = font->glyph("d")) { CharstringBounds::bounds(font_transform, CharstringContext(font, t1cs), bb, wx); if (bb[3]) fprintf(outf, "Ascender %d\n", (int) ceil(bb[3])); } if (Type1Charstring *t1cs = font->glyph("p")) { CharstringBounds::bounds(font_transform, CharstringContext(font, t1cs), bb, wx); if (bb[1]) fprintf(outf, "Descender %d\n", (int) floor(bb[1])); } Vector vd; if (Type1Definition *t1d = font->p_dict("StdHW")) if (t1d->value_numvec(vd) && vd.size() > 0) fprintf(outf, "StdHW %d\n", (int) ceil(vd[0])); if (Type1Definition *t1d = font->p_dict("StdVW")) if (t1d->value_numvec(vd) && vd.size() > 0) fprintf(outf, "StdVW %d\n", (int) ceil(vd[0])); double fontbb[4] = { 1000000, 1000000, -1000000, -1000000 }; for (int i = 0; i < font->nglyphs(); ++i) { CharstringBounds::bounds(font_transform, CharstringContext(font, font->glyph(i)), bb, wx); fontbb[0] = std::min(fontbb[0], bb[0]); fontbb[1] = std::min(fontbb[1], bb[1]); fontbb[2] = std::max(fontbb[2], bb[2]); fontbb[3] = std::max(fontbb[3], bb[3]); } fprintf(outf, "FontBBox %d %d %d %d\n", (int) floor(fontbb[0]), (int) floor(fontbb[1]), (int) ceil(fontbb[2]), (int) ceil(fontbb[3])); fprintf(outf, "FontName %s\n", font->font_name().c_str()); int nglyphs = font->nglyphs(); PermString dot_notdef(".notdef"); if (font->glyph(dot_notdef)) --nglyphs; fprintf(outf, "Characters %d\n", nglyphs); fprintf(outf, "StartCharMetrics %d\n", nglyphs); HashMap done_yet(0); done_yet.insert(dot_notdef, 1); if (Type1Encoding *enc = font->type1_encoding()) { for (int i = 0; i < 256; ++i) { PermString n = enc->elt(i); if (!done_yet[n]) if (Type1Charstring *g = font->glyph(n)) { write_char(outf, i, n, g, font_transform, font); done_yet.insert(n, true); } } } for (int i = 0; i < font->nglyphs(); ++i) { PermString n = font->glyph_name(i); if (!done_yet[n]) write_char(outf, -1, n, font->glyph(i), font_transform, font); } fprintf(outf, "EndCharMetrics\n"); fprintf(outf, "EndFontMetrics\n"); } int main(int argc, char *argv[]) { PsresDatabase *psres = new PsresDatabase; psres->add_psres_path(getenv("PSRESOURCEPATH"), 0, false); Clp_Parser *clp = Clp_NewParser(argc, (const char * const *)argv, sizeof(options) / sizeof(options[0]), options); program_name = Clp_ProgramName(clp); ErrorHandler *errh = ErrorHandler::static_initialize(new FileErrorHandler(stderr)); const char *output_file = 0; Vector glyph_patterns; while (1) { int opt = Clp_Next(clp); switch (opt) { case OUTPUT_OPT: output_file: if (output_file) errh->fatal("output file already specified"); output_file = clp->vstr; break; case VERSION_OPT: printf("t1rawafm (LCDF typetools) %s\n", VERSION); printf("Copyright (C) 2008-2019 Eddie Kohler\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); exit(0); break; case HELP_OPT: usage(); exit(0); break; case Clp_NotOption: if (font) goto output_file; else do_file(clp->vstr, psres, errh); break; case Clp_Done: goto done; case Clp_BadOption: usage_error(errh, 0); break; default: break; } } done: if (!font) do_file(0, psres, errh); FILE *outf; if (!output_file || strcmp(output_file, "-") == 0) outf = stdout; else { outf = fopen(output_file, "w"); if (!outf) errh->fatal("%s: %s", output_file, strerror(errno)); } write_afm(outf, font); exit(0); } lcdf-typetools-2.108/t1rawafm/Makefile.in0000644000175000017500000005104013423376574015222 00000000000000# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : bin_PROGRAMS = t1rawafm$(EXEEXT) subdir = t1rawafm ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/lcdf-typetools.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/autoconf.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" PROGRAMS = $(bin_PROGRAMS) am_t1rawafm_OBJECTS = t1rawafm.$(OBJEXT) t1rawafm_OBJECTS = $(am_t1rawafm_OBJECTS) t1rawafm_DEPENDENCIES = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(t1rawafm_SOURCES) DIST_SOURCES = $(t1rawafm_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KPATHSEA_DEPEND = @KPATHSEA_DEPEND@ KPATHSEA_INCLUDES = @KPATHSEA_INCLUDES@ KPATHSEA_LIBS = @KPATHSEA_LIBS@ KPATHSEA_RULE = @KPATHSEA_RULE@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SELECTED_SUBDIRS = @SELECTED_SUBDIRS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TEMPLATE_OBJS = @TEMPLATE_OBJS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ encdir = @encdir@ exec_prefix = @exec_prefix@ glyphlistdir = @glyphlistdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign man_MANS = t1rawafm.1 t1rawafm_SOURCES = t1rawafm.cc t1rawafm_LDADD = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_CPPFLAGS = -I$(srcdir)/../include CLEANFILES = @TEMPLATE_OBJS@ EXTRA_DIST = t1rawafm.1 all: all-am .SUFFIXES: .SUFFIXES: .cc .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign t1rawafm/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign t1rawafm/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) t1rawafm$(EXEEXT): $(t1rawafm_OBJECTS) $(t1rawafm_DEPENDENCIES) $(EXTRA_t1rawafm_DEPENDENCIES) @rm -f t1rawafm$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(t1rawafm_OBJECTS) $(t1rawafm_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1rawafm.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-man uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-binPROGRAMS install-data install-data-am \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-man1 install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-binPROGRAMS uninstall-man uninstall-man1 .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lcdf-typetools-2.108/t1rawafm/Makefile.am0000664000175000017500000000047612732752520015211 00000000000000## Process this file with automake to produce Makefile.in AUTOMAKE_OPTIONS = foreign bin_PROGRAMS = t1rawafm man_MANS = t1rawafm.1 t1rawafm_SOURCES = t1rawafm.cc t1rawafm_LDADD = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_CPPFLAGS = -I$(srcdir)/../include CLEANFILES = @TEMPLATE_OBJS@ EXTRA_DIST = t1rawafm.1 lcdf-typetools-2.108/cfftot1/0000755000175000017500000000000013423377073013054 500000000000000lcdf-typetools-2.108/cfftot1/cfftot1.10000644000175000017500000000343113423376706014427 00000000000000.ds V 2.108 .de M .BR "\\$1" "(\\$2)\\$3" .. .de Sp .if n .sp .if t .sp 0.4 .. .TH CFFTOT1 1 "LCDF Typetools" "Version \*V" .SH NAME cfftot1 \- convert PostScript font from CFF to Type 1 .SH SYNOPSIS .B cfftot1 \%[\fB\-a\fR] \%[\fIinput\fR [\fIoutput\fR]] .SH DESCRIPTION .BR Cfftot1 converts PostScript font programs in the Compact Font Format (CFF) into Type 1 font programs in PFB or PFA format, preserving all hints that can be represented in Type 1. The input file should be a raw CFF file or a PostScript-flavored OpenType font. If the file .I output is not specified output goes to the standard output. If the file .I input is not specified input comes from the standard input. ' .SH OPTIONS .PD 0 .TP 5 .BI \-a "\fR, " \-\-pfa Output font in ASCII PFA format. ' .Sp .TP 5 .BI \-b "\fR, " \-\-pfb Output font in binary PFB format. This is the default. ' .Sp .TP 5 .BI \-n " name\fR, " \-\-name " name" Output the CFF's component font named .IR name . CFF files can contain more than one font, although few do. Use this option to select a particular font from a multi-font collection. By default cfftot1 chooses the collection's first font. ' .Sp .TP 5 .BI \-o " file\fR, " \-\-output " file" Write output font to .IR file instead of the standard output. ' .Sp .TP 5 .BR \-q ", " \-\-quiet Do not generate any error messages. ' .Sp .TP 5 .BR \-h ", " \-\-help Print usage information and exit. ' .Sp .TP 5 .BR \-v ", " \-\-version Print the version number and some short non-warranty information and exit. .PD ' .SH "SEE ALSO" .LP .M t1binary 1 , .M t1ascii 1 .LP .I "Adobe Type 1 Font Format" .LP Adobe Technical Notes #5176, .IR "The Compact Font Format Specification" , and #5177, .I "The Type 2 Charstring Format" .LP .IR "OpenType Specification" , Version 1.4 ' .SH AUTHOR Eddie Kohler (ekohler@gmail.com) lcdf-typetools-2.108/cfftot1/maket1font.cc0000644000175000017500000005014013423375327015354 00000000000000/* maket1font.{cc,hh} -- translate CFF fonts to Type 1 fonts * * Copyright (c) 2002-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include "maket1font.hh" #include #include #include #include #include #include #include using namespace Efont; typedef unsigned CsRef; enum { CSR_GLYPH = 0x00000000, CSR_SUBR = 0x80000000, CSR_GSUBR = 0xC0000000, CSR_TYPE = 0xC0000000, CSR_NUM = 0x3FFFFFFF }; class MakeType1CharstringInterp : public Type1CharstringGenInterp { public: MakeType1CharstringInterp(int precision = 5); ~MakeType1CharstringInterp(); Type1Font *output() const { return _output; } void run(const CharstringProgram *, Type1Font *, PermString glyph_definer, ErrorHandler *); void run(const CharstringContext &, Type1Charstring &, ErrorHandler *); bool type2_command(int, const uint8_t *, int *); String landmark(ErrorHandler *errh) const; class Subr; private: // output Type1Font *_output; int _flex_message; // subroutines int _subr_bias; int _gsubr_bias; mutable Vector _glyphs; mutable Vector _subrs; mutable Vector _gsubrs; Subr *_cur_subr; int _cur_glyph; Subr *csr_subr(CsRef, bool force) const; Type1Charstring *csr_charstring(CsRef) const; }; class MakeType1CharstringInterp::Subr { public: Subr(CsRef csr) : _csr(csr), _output_subrno(-1), _stamp(0) { } bool up_to_date() const { return _stamp == max_stamp; } void update() { _stamp = max_stamp; } static void bump_date() { max_stamp++; } //String name(const MakeType1CharstringInterp *) const; Type1Charstring *charstring(const MakeType1CharstringInterp *) const; int ncalls() const { return _calls.size(); } Subr *call(int i) const { return _calls[i]; } bool has_call(Subr *) const; struct Caller { Subr *subr; int pos; int len; Caller(Subr *s, int p, int l) : subr(s), pos(p), len(l) { } String charstring(MakeType1CharstringInterp *mcsi) const { Type1Charstring *t1cs = subr->charstring(mcsi); return t1cs->substring(pos, len); } }; int ncallers() const { return _callers.size(); } const Caller &caller(int i) const { return _callers[i]; } void add_call(Subr *s) { _calls.push_back(s); } void add_caller(Subr *s, int pos, int len); int output_subrno() const { return _output_subrno; } void set_output_subrno(int n) { _output_subrno = n; } void transfer_nested_calls(int pos, int length, Subr *new_caller) const; void change_callers(Subr *, int pos, int length, int new_length); bool unify(MakeType1CharstringInterp *); private: CsRef _csr; Vector _calls; Vector _callers; int _output_subrno; int _stamp; static int max_stamp; friend class MakeType1CharstringInterp; }; int MakeType1CharstringInterp::Subr::max_stamp = 1; inline void MakeType1CharstringInterp::Subr::add_caller(Subr *s, int pos, int len) { _callers.push_back(Caller(s, pos, len)); } bool MakeType1CharstringInterp::Subr::has_call(Subr *s) const { for (int i = 0; i < _calls.size(); i++) if (_calls[i] == s) return true; return false; } /***** * MakeType1CharstringInterp **/ MakeType1CharstringInterp::MakeType1CharstringInterp(int precision) : Type1CharstringGenInterp(precision), _flex_message(0) { } MakeType1CharstringInterp::~MakeType1CharstringInterp() { for (int i = 0; i < _glyphs.size(); i++) delete _glyphs[i]; for (int i = 0; i < _subrs.size(); i++) delete _subrs[i]; for (int i = 0; i < _gsubrs.size(); i++) delete _gsubrs[i]; } String MakeType1CharstringInterp::landmark(ErrorHandler *errh) const { if (_cur_glyph >= 0 && _cur_glyph < program()->nglyphs()) return errh->format("glyph %<%s%>", program()->glyph_name(_cur_glyph).c_str()); else return String(); } // subroutines MakeType1CharstringInterp::Subr * MakeType1CharstringInterp::csr_subr(CsRef csr, bool force) const { Vector *vp; if ((csr & CSR_TYPE) == CSR_SUBR) vp = &_subrs; else if ((csr & CSR_TYPE) == CSR_GSUBR) vp = &_gsubrs; else if ((csr & CSR_TYPE) == CSR_GLYPH) vp = &_glyphs; else return 0; int n = (csr & CSR_NUM); if (n >= vp->size()) return 0; Subr *&what = (*vp)[n]; if (!what && force) what = new Subr(csr); return what; } #if 0 String MakeType1CharstringInterp::Subr::name(const MakeType1CharstringInterp *mcsi) const { int n = (_csr & CSR_NUM); switch (_csr & CSR_TYPE) { case CSR_SUBR: return "subr" + String(n); case CSR_GSUBR: return "gsubr" + String(n); case CSR_GLYPH: if (String name = mcsi->output()->glyph_name(n)) return name; else return "??glyph" + String(n) + "??"; default: return ""; } } #endif Type1Charstring * MakeType1CharstringInterp::Subr::charstring(const MakeType1CharstringInterp *mcsi) const { int n = (_csr & CSR_NUM); switch (_csr & CSR_TYPE) { case CSR_SUBR: case CSR_GSUBR: if (_output_subrno >= 0) return static_cast(mcsi->output()->subr(_output_subrno)); return 0; case CSR_GLYPH: return static_cast(mcsi->output()->glyph(n)); default: return 0; } } void MakeType1CharstringInterp::Subr::transfer_nested_calls(int pos, int length, Subr *new_caller) const { int right = pos + length; for (int i = 0; i < _calls.size(); i++) { Subr *cs = _calls[i]; // 11.Jul.2006 - remember not to shift the new caller's records! (Michael Zedler) if (cs != new_caller) for (int j = 0; j < cs->_callers.size(); j++) { Caller &c = cs->_callers[j]; if (c.subr == this && pos <= c.pos && c.pos + c.len <= right) { // shift caller to point at the subroutine c.subr = new_caller; c.pos -= pos; new_caller->add_call(cs); } } } } void MakeType1CharstringInterp::Subr::change_callers(Subr *caller, int pos, int length, int new_length) { if (up_to_date()) return; update(); int right = pos + length; int delta = new_length - length; for (int i = 0; i < _callers.size(); i++) { Caller &c = _callers[i]; if (c.subr != caller) /* nada */; else if (pos <= c.pos && c.pos + c.len <= right) { // erase //if (c.debug) fprintf(stderr, " ERASE caller %08x:%d+%d [%d+%d]\n", c.subr->_csr, c.pos, c.len, pos, length); c.subr = 0; } else if (right <= c.pos) { //if (c.debug) fprintf(stderr, " ADJUST caller %08x:%d+%d -> %d+%d [%d+%d]\n", c.subr->_csr, c.pos, c.len, c.pos+delta, c.len, pos, length); c.pos += delta; } else if (c.pos <= pos && right <= c.pos + c.len) { //if (c.debug) fprintf(stderr, " ADJUST caller %08x:%d+%d -> %d+%d [%d+%d]\n", c.subr->_csr, c.pos, c.len, c.pos, c.len+delta, pos, length); c.len += delta; } else c.subr = 0; } } bool MakeType1CharstringInterp::Subr::unify(MakeType1CharstringInterp *mcsi) { // clean up caller list for (int i = 0; i < _callers.size(); i++) if (!_callers[i].subr) { _callers[i] = _callers.back(); _callers.pop_back(); i--; } if (!_callers.size()) return false; assert(!_calls.size()); // because this hasn't been unified yet // Find the smallest shared complete charstring. String substr = _callers[0].charstring(mcsi); int suboff = 0; for (int i = 1; i < _callers.size(); i++) { String substr1 = _callers[i].charstring(mcsi); const char *d = substr.data() + suboff, *d1 = substr1.data(); const char *dx = substr.data() + substr.length(), *d1x = d1 + substr1.length(); while (dx > d && d1x > d1 && dx[-1] == d1x[-1]) dx--, d1x--; if (d1x != d1) { // 8.13.2013 -- We might have stopped in the middle of a number // or command in d1 -- even if we absorbed all of d! For // example, maybe d's version is "15 rlineto" (encoded "154 5"), // and our version is "518 rlineto" (encoded "248 154 5")! So // whenever we stop before the end of d1, we must adjust our // position to the next caret in d1, which, in the example, // would be after "248 154" and before "5". int suboff1 = Type1Charstring(substr1).first_caret_after(d1x - d1); dx += suboff1 - (d1x - d1); } suboff = dx - substr.data(); } substr = substr.substring(Type1Charstring(substr).first_caret_after(suboff)); if (!substr.length()) return false; for (int i = 0; i < _callers.size(); i++) { Caller &c = _callers[i]; if (int delta = c.len - substr.length()) { //if (c.debug) fprintf(stderr, " PREFIX caller %08x:%d+%d -> %d+%d [%s]\n", c.subr->_csr, c.pos, c.len, c.pos+delta, c.len+delta, CharstringUnparser::unparse(Type1Charstring(substr)).c_str()); c.pos += delta; c.len -= delta; } } // otherwise, success _output_subrno = mcsi->output()->nsubrs(); mcsi->output()->set_subr(_output_subrno, Type1Charstring(substr + "\013")); // This subr has become real, so it is suitable for later unifications. // Mark it as having called any subroutines contained completely within itself. // How to do this? Look at one caller, and go over all its calls. _callers[0].subr->transfer_nested_calls(_callers[0].pos, _callers[0].len, this); // adapt callers String callsubr_string = Type1CharstringGen::callsubr_string(_output_subrno); for (int i = 0; i < _callers.size(); i++) // 13.Jun.2003 - must check whether _callers[i].subr exists: if we // called a subroutine more than once, change_callers() might have // zeroed it out. if (_callers[i].subr && _callers[i].subr != this) { Subr::Caller c = _callers[i]; c.subr->charstring(mcsi)->assign_substring(c.pos, c.len, callsubr_string); Subr::bump_date(); for (int j = 0; j < c.subr->ncalls(); j++) c.subr->call(j)->change_callers(c.subr, c.pos, c.len, callsubr_string.length()); assert(!_callers[i].subr); } // this subr is no longer "called"/interpolated from anywhere _callers.clear(); //fprintf(stderr, "Succeeded %x\n", _csr); return true; } // running bool MakeType1CharstringInterp::type2_command(int cmd, const uint8_t *data, int *left) { switch (cmd) { case Cs::cCallsubr: case Cs::cCallgsubr: if (subr_depth() < MAX_SUBR_DEPTH && size() == 1) { //fprintf(stderr, "succeeded %d\n", (int) top()); bool g = (cmd == Cs::cCallgsubr); CsRef csref = ((int)top() + program()->xsubr_bias(g)) | (g ? CSR_GSUBR : CSR_SUBR); Subr *callee = csr_subr(csref, true); if (callee) _cur_subr->add_call(callee); int left = csgen().length(); bool more = callxsubr_command(g); int right = csgen().length(); if (error() >= 0 && callee) callee->add_caller(_cur_subr, left, right - left); return more; } else { //fprintf(stderr, "failed %d\n", (int) top()); goto normal; } normal: default: return CharstringInterp::type2_command(cmd, data, left); } } void MakeType1CharstringInterp::run(const CharstringContext &g, Type1Charstring &out, ErrorHandler *errh) { Type1CharstringGenInterp::run(g, out); if (Type1CharstringGenInterp::had_bad_flex() && !(_flex_message & 1)) { errh->lwarning(landmark(errh), "complex flex hint replaced with curves"); errh->message("(This font contains flex hints prohibited by Type 1. They%,ve been\nreplaced by ordinary curves.)"); _flex_message |= 1; } #if !HAVE_ADOBE_CODE if (Type1CharstringGenInterp::had_flex() && !(_flex_message & 2)) { errh->lwarning(landmark(errh), "flex hints required"); errh->message("(This program was compiled without Adobe code for flex hint support,\nso its output may not work on all devices.)"); _flex_message |= 2; } if (Type1CharstringGenInterp::had_hr() && !(_flex_message & 4)) { errh->lwarning(landmark(errh), "hint replacement required"); errh->message("(This program was compiled without Adobe code for hint replacement,\nso its output may not work on all devices.)"); _flex_message |= 4; } #endif } void MakeType1CharstringInterp::run(const CharstringProgram *program, Type1Font *output, PermString glyph_definer, ErrorHandler *errh) { _output = output; set_hint_replacement_storage(output); _glyphs.assign(program->nglyphs(), 0); _subrs.assign(program->nsubrs(), 0); _subr_bias = program->subr_bias(); _gsubrs.assign(program->ngsubrs(), 0); _gsubr_bias = program->gsubr_bias(); // run over the glyphs int nglyphs = program->nglyphs(); Type1Charstring receptacle; for (int i = 0; i < nglyphs; i++) { _cur_subr = _glyphs[i] = new Subr(CSR_GLYPH | i); _cur_glyph = i; run(program->glyph_context(i), receptacle, errh); #if 0 PermString n = program->glyph_name(i); if (i == 408 || i == 20) { fprintf(stderr, "%d: %s was %s\n", i, n.c_str(), CharstringUnparser::unparse(*program->glyph(i)).c_str()); fprintf(stderr, " now %s\n", CharstringUnparser::unparse(receptacle).c_str()); fprintf(stderr, " *** %d.%d: %s\n", 134, 30, CharstringUnparser::unparse(Type1Charstring(receptacle.data_string().substring(134, 30))).c_str()); } #endif PermString name = program->glyph_name(i); if (output->glyph(name)) { errh->warning("glyph %<%s%> defined more than once", name.c_str()); int i = 1; do { name = program->glyph_name(i) + String(".") + String(i); ++i; } while (output->glyph(name)); } output->add_glyph(Type1Subr::make_glyph(name, receptacle, glyph_definer)); } // unify Subrs for (int i = 0; i < _subrs.size(); i++) if (_subrs[i]) _subrs[i]->unify(this); for (int i = 0; i < _gsubrs.size(); i++) if (_gsubrs[i]) _gsubrs[i]->unify(this); } /***** * main **/ static void add_number_def(Type1Font *output, int dict, PermString name, const Cff::Font *font, Cff::DictOperator op) { double v; if (font->dict_value(op, &v)) output->add_definition(dict, Type1Definition::make(name, v, "def")); } static void add_delta_def(Type1Font *output, int dict, PermString name, const Cff::Font *font, Cff::DictOperator op) { Vector vec; if (font->dict_value(op, vec)) { for (int i = 1; i < vec.size(); i++) vec[i] += vec[i - 1]; StringAccum sa; for (int i = 0; i < vec.size(); i++) sa << (i ? ' ' : '[') << vec[i]; sa << ']'; output->add_definition(dict, Type1Definition::make_literal(name, sa.take_string(), (dict == Type1Font::dP ? "|-" : "readonly def"))); } } Type1Font * create_type1_font(Cff::Font *font, ErrorHandler *errh) { String version = font->dict_string(Cff::oVersion); Type1Font *output = Type1Font::skeleton_make(font->font_name(), version); output->skeleton_comments_end(); StringAccum sa; // FontInfo dictionary if (version) output->add_definition(Type1Font::dFI, Type1Definition::make_string("version", version, "readonly def")); if (String s = font->dict_string(Cff::oNotice)) output->add_definition(Type1Font::dFI, Type1Definition::make_string("Notice", s, "readonly def")); if (String s = font->dict_string(Cff::oCopyright)) output->add_definition(Type1Font::dFI, Type1Definition::make_string("Copyright", s, "readonly def")); if (String s = font->dict_string(Cff::oFullName)) output->add_definition(Type1Font::dFI, Type1Definition::make_string("FullName", s, "readonly def")); if (String s = font->dict_string(Cff::oFamilyName)) output->add_definition(Type1Font::dFI, Type1Definition::make_string("FamilyName", s, "readonly def")); if (String s = font->dict_string(Cff::oWeight)) output->add_definition(Type1Font::dFI, Type1Definition::make_string("Weight", s, "readonly def")); double v; if (font->dict_value(Cff::oIsFixedPitch, &v)) output->add_definition(Type1Font::dFI, Type1Definition::make_literal("isFixedPitch", (v ? "true" : "false"), "def")); add_number_def(output, Type1Font::dFI, "ItalicAngle", font, Cff::oItalicAngle); add_number_def(output, Type1Font::dFI, "UnderlinePosition", font, Cff::oUnderlinePosition); add_number_def(output, Type1Font::dFI, "UnderlineThickness", font, Cff::oUnderlineThickness); output->skeleton_fontinfo_end(); // Encoding, other font dictionary entries output->add_item(font->type1_encoding_copy()); font->dict_value(Cff::oPaintType, &v); output->add_definition(Type1Font::dF, Type1Definition::make("PaintType", v, "def")); output->add_definition(Type1Font::dF, Type1Definition::make("FontType", 1.0, "def")); Vector vec; if (font->dict_value(Cff::oFontMatrix, vec) && vec.size() == 6) { sa << '[' << vec[0] << ' ' << vec[1] << ' ' << vec[2] << ' ' << vec[3] << ' ' << vec[4] << ' ' << vec[5] << ']'; output->add_definition(Type1Font::dF, Type1Definition::make_literal("FontMatrix", sa.take_string(), "readonly def")); } else output->add_definition(Type1Font::dF, Type1Definition::make_literal("FontMatrix", "[0.001 0 0 0.001 0 0]", "readonly def")); add_number_def(output, Type1Font::dF, "StrokeWidth", font, Cff::oStrokeWidth); add_number_def(output, Type1Font::dF, "UniqueID", font, Cff::oUniqueID); if (font->dict_value(Cff::oXUID, vec) && vec.size()) { for (int i = 0; i < vec.size(); i++) sa << (i ? ' ' : '[') << vec[i]; sa << ']'; output->add_definition(Type1Font::dF, Type1Definition::make_literal("XUID", sa.take_string(), "readonly def")); } if (font->dict_value(Cff::oFontBBox, vec) && vec.size() == 4) { sa << '{' << vec[0] << ' ' << vec[1] << ' ' << vec[2] << ' ' << vec[3] << '}'; output->add_definition(Type1Font::dF, Type1Definition::make_literal("FontBBox", sa.take_string(), "readonly def")); } else output->add_definition(Type1Font::dF, Type1Definition::make_literal("FontBBox", "{0 0 0 0}", "readonly def")); output->skeleton_fontdict_end(); // Private dictionary add_delta_def(output, Type1Font::dP, "BlueValues", font, Cff::oBlueValues); add_delta_def(output, Type1Font::dP, "OtherBlues", font, Cff::oOtherBlues); add_delta_def(output, Type1Font::dP, "FamilyBlues", font, Cff::oFamilyBlues); add_delta_def(output, Type1Font::dP, "FamilyOtherBlues", font, Cff::oFamilyOtherBlues); add_number_def(output, Type1Font::dP, "BlueScale", font, Cff::oBlueScale); add_number_def(output, Type1Font::dP, "BlueShift", font, Cff::oBlueShift); add_number_def(output, Type1Font::dP, "BlueFuzz", font, Cff::oBlueFuzz); if (font->dict_value(Cff::oStdHW, &v)) output->add_definition(Type1Font::dP, Type1Definition::make_literal("StdHW", String("[") + String(v) + "]", "|-")); if (font->dict_value(Cff::oStdVW, &v)) output->add_definition(Type1Font::dP, Type1Definition::make_literal("StdVW", String("[") + String(v) + "]", "|-")); add_delta_def(output, Type1Font::dP, "StemSnapH", font, Cff::oStemSnapH); add_delta_def(output, Type1Font::dP, "StemSnapV", font, Cff::oStemSnapV); if (font->dict_value(Cff::oForceBold, &v)) output->add_definition(Type1Font::dP, Type1Definition::make_literal("ForceBold", (v ? "true" : "false"), "def")); add_number_def(output, Type1Font::dP, "LanguageGroup", font, Cff::oLanguageGroup); add_number_def(output, Type1Font::dP, "ExpansionFactor", font, Cff::oExpansionFactor); add_number_def(output, Type1Font::dP, "UniqueID", font, Cff::oUniqueID); output->add_definition(Type1Font::dP, Type1Definition::make_literal("MinFeature", "{16 16}", "|-")); output->add_definition(Type1Font::dP, Type1Definition::make_literal("password", "5839", "def")); output->add_definition(Type1Font::dP, Type1Definition::make_literal("lenIV", "0", "def")); output->skeleton_private_end(); output->skeleton_common_subrs(); // add glyphs MakeType1CharstringInterp maker(5); maker.run(font, output, " |-", errh); return output; } #include lcdf-typetools-2.108/cfftot1/cfftot1.cc0000644000175000017500000001522213423375327014653 00000000000000/* cfftot1.cc -- driver for translating CFF fonts to Type 1 fonts * * Copyright (c) 2002-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include "maket1font.hh" #include #include #include #include #include #include #include #include #ifdef HAVE_CTIME # include #endif #if defined(_MSDOS) || defined(_WIN32) # include # include #endif using namespace Efont; #define VERSION_OPT 301 #define HELP_OPT 302 #define QUIET_OPT 303 #define PFB_OPT 304 #define PFA_OPT 305 #define OUTPUT_OPT 306 #define NAME_OPT 307 const Clp_Option options[] = { { "ascii", 'a', PFA_OPT, 0, 0 }, { "binary", 'b', PFB_OPT, 0, 0 }, { "help", 'h', HELP_OPT, 0, 0 }, { "name", 'n', NAME_OPT, Clp_ValString, 0 }, { "output", 'o', OUTPUT_OPT, Clp_ValString, 0 }, { "pfa", 'a', PFA_OPT, 0, 0 }, { "pfb", 'b', PFB_OPT, 0, 0 }, { "quiet", 'q', QUIET_OPT, 0, Clp_Negate }, { "version", 'v', VERSION_OPT, 0, 0 }, }; static const char *program_name; static bool binary = true; void usage_error(ErrorHandler *errh, const char *error_message, ...) { va_list val; va_start(val, error_message); if (!error_message) errh->message("Usage: %s [OPTIONS] [FONTFILE [OUTPUTFILE]]", program_name); else errh->xmessage(ErrorHandler::e_error, error_message, val); errh->message("Type %s --help for more information.", program_name); exit(1); } void usage() { FileErrorHandler uerrh(stdout); uerrh.message("\ % translates a PostScript font from the Compact Font Format (CFF) to\n\ the usual Type 1 format. The input file should be either a raw CFF font or a\n\ PostScript-flavored OpenType font. The result, which is usually written to the\n\ standard output, is written in PFB or PFA format.\n\ \n\ Usage: %s [OPTIONS] [FONTFILE [OUTPUTFILE]]\n\ \n\ Options:\n\ -a, --pfa Output PFA font.\n\ -b, --pfb Output PFB font. This is the default.\n\ -n, --name=NAME Select font NAME from CFF.\n\ -o, --output=FILE Write output to FILE.\n\ -q, --quiet Do not generate any error messages.\n\ -h, --help Print this message and exit.\n\ -v, --version Print version number and exit.\n\ \n\ Report bugs to .\n", program_name); } // MAIN static void do_file(const char *infn, const char *outfn, PermString name, ErrorHandler *errh) { FILE *f; if (!infn || strcmp(infn, "-") == 0) { f = stdin; infn = ""; #if defined(_MSDOS) || defined(_WIN32) _setmode(_fileno(f), _O_BINARY); #endif } else if (!(f = fopen(infn, "rb"))) errh->fatal("%s: %s", infn, strerror(errno)); int c = getc(f); ungetc(c, f); Cff::Font *font = 0; if (c == EOF) errh->fatal("%s: empty file", infn); if (c != 1 && c != 'O') errh->fatal("%s: not a CFF or OpenType/CFF font", infn); StringAccum sa(150000); int amt; do { if (char *x = sa.reserve(32768)) { amt = fread(x, 1, 32768, f); sa.adjust_length(amt); } else amt = 0; } while (amt != 0); if (!feof(f) || ferror(f)) errh->lerror(infn, "%s", strerror(errno)); if (f != stdin) fclose(f); ContextErrorHandler cerrh(errh, "While processing %s:", infn); cerrh.set_indent(0); String data = sa.take_string(); unsigned units_per_em = 0; if (c == 'O') { Efont::OpenType::Font font(data, &cerrh); data = font.table("CFF"); units_per_em = font.units_per_em(); } Cff *cff = new Cff(data, units_per_em, &cerrh); Cff::FontParent *fp = cff->font(name, &cerrh); if (errh->nerrors() == 0 && !(font = dynamic_cast(fp))) errh->fatal("%s: CID-keyed fonts not supported", infn); if (errh->nerrors() > 0) return; Type1Font *font1 = create_type1_font(font, &cerrh); if (!outfn || strcmp(outfn, "-") == 0) { f = stdout; outfn = ""; } else if (!(f = fopen(outfn, "wb"))) errh->fatal("%s: %s", outfn, strerror(errno)); if (binary) { #if defined(_MSDOS) || defined(_WIN32) _setmode(_fileno(f), _O_BINARY); #endif Type1PFBWriter t1w(f); font1->write(t1w); } else { Type1PFAWriter t1w(f); font1->write(t1w); } if (f != stdout) fclose(f); } int main(int argc, char *argv[]) { Clp_Parser *clp = Clp_NewParser(argc, (const char * const *)argv, sizeof(options) / sizeof(options[0]), options); program_name = Clp_ProgramName(clp); ErrorHandler *errh = ErrorHandler::static_initialize(new FileErrorHandler(stderr, String(program_name) + ": ")); const char *input_file = 0; const char *output_file = 0; const char *font_name = 0; while (1) { int opt = Clp_Next(clp); switch (opt) { case PFA_OPT: binary = false; break; case PFB_OPT: binary = true; break; case NAME_OPT: if (font_name) usage_error(errh, "font name specified twice"); font_name = clp->vstr; break; case QUIET_OPT: if (clp->negated) errh = ErrorHandler::default_handler(); else errh = new SilentErrorHandler; break; case VERSION_OPT: printf("cfftot1 (LCDF typetools) %s\n", VERSION); printf("Copyright (C) 2002-2019 Eddie Kohler\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); exit(0); break; case HELP_OPT: usage(); exit(0); break; case OUTPUT_OPT: output_file: if (output_file) usage_error(errh, "output file specified twice"); output_file = clp->vstr; break; case Clp_NotOption: if (input_file && output_file) usage_error(errh, "too many arguments"); else if (input_file) goto output_file; else input_file = clp->vstr; break; case Clp_Done: goto done; case Clp_BadOption: usage_error(errh, 0); break; default: break; } } done: do_file(input_file, output_file, font_name, errh); return (errh->nerrors() == 0 ? 0 : 1); } lcdf-typetools-2.108/cfftot1/maket1font.hh0000664000175000017500000000030712732752520015364 00000000000000#ifndef EFONT_MAKET1FONT_HH #define EFONT_MAKET1FONT_HH #include namespace Efont { class Type1Font; } Efont::Type1Font *create_type1_font(Efont::Cff::Font *, ErrorHandler *); #endif lcdf-typetools-2.108/cfftot1/Makefile.in0000644000175000017500000005207613423376574015060 00000000000000# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : bin_PROGRAMS = cfftot1$(EXEEXT) subdir = cfftot1 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/lcdf-typetools.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/autoconf.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" PROGRAMS = $(bin_PROGRAMS) am_cfftot1_OBJECTS = cfftot1.$(OBJEXT) maket1font.$(OBJEXT) cfftot1_OBJECTS = $(am_cfftot1_OBJECTS) cfftot1_DEPENDENCIES = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(cfftot1_SOURCES) DIST_SOURCES = $(cfftot1_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KPATHSEA_DEPEND = @KPATHSEA_DEPEND@ KPATHSEA_INCLUDES = @KPATHSEA_INCLUDES@ KPATHSEA_LIBS = @KPATHSEA_LIBS@ KPATHSEA_RULE = @KPATHSEA_RULE@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SELECTED_SUBDIRS = @SELECTED_SUBDIRS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TEMPLATE_OBJS = @TEMPLATE_OBJS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ encdir = @encdir@ exec_prefix = @exec_prefix@ glyphlistdir = @glyphlistdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign man_MANS = cfftot1.1 cfftot1_SOURCES = cfftot1.cc \ maket1font.cc maket1font.hh cfftot1_LDADD = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_CPPFLAGS = -I$(srcdir)/../include CLEANFILES = @TEMPLATE_OBJS@ EXTRA_DIST = cfftot1.1 all: all-am .SUFFIXES: .SUFFIXES: .cc .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign cfftot1/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign cfftot1/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) cfftot1$(EXEEXT): $(cfftot1_OBJECTS) $(cfftot1_DEPENDENCIES) $(EXTRA_cfftot1_DEPENDENCIES) @rm -f cfftot1$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(cfftot1_OBJECTS) $(cfftot1_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cfftot1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maket1font.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-man uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-binPROGRAMS install-data install-data-am \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-man1 install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-binPROGRAMS uninstall-man uninstall-man1 .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lcdf-typetools-2.108/cfftot1/Makefile.am0000664000175000017500000000052712732752520015032 00000000000000## Process this file with automake to produce Makefile.in AUTOMAKE_OPTIONS = foreign bin_PROGRAMS = cfftot1 man_MANS = cfftot1.1 cfftot1_SOURCES = cfftot1.cc \ maket1font.cc maket1font.hh cfftot1_LDADD = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_CPPFLAGS = -I$(srcdir)/../include CLEANFILES = @TEMPLATE_OBJS@ EXTRA_DIST = cfftot1.1 lcdf-typetools-2.108/include/0000755000175000017500000000000013423377072013130 500000000000000lcdf-typetools-2.108/include/efont/0000755000175000017500000000000013423377072014243 500000000000000lcdf-typetools-2.108/include/efont/t1unparser.hh0000664000175000017500000000172012732752520016607 00000000000000// -*- related-file-name: "../../libefont/t1unparser.cc" -*- #ifndef EFONT_T1UNPARSER_HH #define EFONT_T1UNPARSER_HH #include #include namespace Efont { class CharstringUnparser : public CharstringInterp { public: CharstringUnparser(); CharstringUnparser(const CharstringUnparser &); const String &indent() const { return _indent; } void set_indent(const String &s) { _indent = s; } void set_one_command_per_line(bool b) { _one_command_per_line = b; } void clear(); bool number(double); bool type1_command(int); bool type2_command(int, const unsigned char *, int *); void act_hintmask(int, const unsigned char *, int); String value(); static String unparse(const Charstring *); static String unparse(const Charstring &); private: String _indent; bool _one_command_per_line; bool _start_of_line; StringAccum _sa; }; } #endif lcdf-typetools-2.108/include/efont/afmparse.hh0000664000175000017500000000340712732752520016305 00000000000000// -*- related-file-name: "../../libefont/afmparse.cc" -*- #ifndef EFONT_AFMPARSE_HH #define EFONT_AFMPARSE_HH #include #include #include namespace Efont { class AfmParser { public: AfmParser(Slurper &); bool ok() const { return _slurper.ok(); } operator Landmark() const { return _slurper.landmark(); } Landmark landmark() const { return _slurper.landmark(); } unsigned lineno() const { return _slurper.lineno(); } const Filename &filename() const { return _slurper.filename(); } bool key_matched() const { return _fail_field >= 0; } int fail_field() const { return _fail_field; } PermString message() const { return _message; } void clear_message() { _message = PermString(); } PermString keyword() const; bool is(const char *, ...); bool isall(const char *, ...); inline bool next_line(); void save_line() { _slurper.save_line(); } void skip_until(unsigned char); unsigned char *cur_line() const { return _pos; } unsigned char first() const { return _pos[0]; } unsigned char operator[](int i) const { return _pos[i]; } bool left() const { return *_pos != 0; } private: Slurper &_slurper; bool _save_line; unsigned char *_line; unsigned char *_pos; int _length; PermString _message; int _fail_field; void static_initialize(); void trim_end(); unsigned char *vis(const char *, va_list); }; inline bool AfmParser::next_line() { _pos = _line = (unsigned char *)_slurper.next_line(); _length = _slurper.cur_line_length(); return _line != 0; } } #endif lcdf-typetools-2.108/include/efont/ttfkern.hh0000644000175000017500000000207613423375327016167 00000000000000// -*- related-file-name: "../../libefont/ttfkern.cc" -*- #ifndef EFONT_TTFKERN_HH #define EFONT_TTFKERN_HH #include namespace Efont { namespace OpenType { class KernTable { public: KernTable(const Data &, ErrorHandler * = 0); // default destructor bool ok() const { return _error >= 0; } bool unparse_automatics(Vector &, ErrorHandler * = 0) const; private: Data _d; int _version; int _error; enum { COV_V0_HORIZONTAL = 0x0001, COV_V0_MINIMUM = 0x0002, COV_V0_CROSS_STREAM = 0x0004, COV_V0_OVERRIDE = 0x0008, COV_V0_FORMAT = 0xFF00, COV_V0_FORMAT0 = 0x0000, COV_V1_VERTICAL = 0x8000, COV_V1_CROSS_STREAM = 0x4000, COV_V1_VARIATION = 0x2000, COV_V1_FORMAT = 0x00FF, COV_V1_FORMAT0 = 0x0000 }; inline uint32_t ntables() const { return _version == 0 ? _d.u16(2) : _d.u32(4); } inline uint32_t first_offset() const { return _version == 0 ? 4 : 8; } inline Data subtable(uint32_t &off) const; }; }} #endif lcdf-typetools-2.108/include/efont/otfdata.hh0000644000175000017500000001474113423375327016136 00000000000000// -*- related-file-name: "../../libefont/otfdata.cc" -*- #ifndef EFONT_OTFDATA_HH #define EFONT_OTFDATA_HH #include #include #include #ifdef HAVE_SYS_TYPES_H # include #endif #if NEED_ARPA_INET_H # include #endif #if HAVE_BYTEORDER_H # include #elif HAVE_NETINET_IN_H # include #elif HAVE_SYS_PARAM_H # include #elif !defined(WIN32) # error "configury disaster! Report this error to ekohler@gmail.com" #endif #ifdef WIN32 # ifdef __MSC_VER # pragma warning (disable: 4290) # endif # include #endif class ErrorHandler; namespace Efont { namespace OpenType { #if HAVE_PRECONDITION_CHECKING #define efont_precondition(x) assert((x)) #else #define efont_precondition(x) #endif class Error { public: String description; Error() : description(String::make_stable("unspecified error")) { } Error(const String &d) : description(d) { } }; class Bounds : public Error { public: Bounds() : Error(String::make_stable("bounds error")) { } }; class Format : public Error { public: Format(const String& name) : Error(name + " format error") { } Format(const String& name, const String& type) : Error(name + " " + type + " format error") { } }; class BlankTable : public Format { public: BlankTable(const String& name) : Format(name, "blank table") { } }; class Data { public: Data() { } Data(const String& str) : _str(str) { _str.align(2); } // default copy constructor // default destructor const String& string() const { return _str; } operator const String&() const { return _str; } operator String::unspecified_bool_type() const { return _str; } const uint8_t *udata() const { return _str.udata(); } int length() const { return _str.length(); } static inline uint16_t u16(const unsigned char* s); static inline uint16_t u16_aligned(const unsigned char* s); static inline int16_t s16(const unsigned char* s); static inline int16_t s16_aligned(const unsigned char* s); static inline uint32_t u32(const unsigned char* s); static inline uint32_t u32_aligned16(const unsigned char* s); static inline uint32_t u32_aligned(const unsigned char* s); static inline int32_t s32(const unsigned char* s); static inline int32_t s32_aligned16(const unsigned char* s); static inline int32_t s32_aligned(const unsigned char* s); inline uint8_t operator[](unsigned offset) const; inline uint16_t u16(unsigned offset) const; inline int16_t s16(unsigned offset) const; inline uint32_t u32(unsigned offset) const; inline int32_t s32(unsigned offset) const; inline uint8_t operator[](int offset) const; inline uint16_t u16(int offset) const; inline int16_t s16(int offset) const; inline uint32_t u32(int offset) const; inline int32_t s32(int offset) const; Data subtable(unsigned offset) const; Data offset_subtable(unsigned offset_offset) const; inline Data substring(int left, int len = -1) const noexcept; void align_long() { _str.align(4); } private: String _str; }; inline uint8_t Data::operator[](unsigned offset) const { if (offset >= static_cast(_str.length())) throw Bounds(); else return _str[offset]; } inline uint16_t Data::u16(const unsigned char* s) { return (s[0] << 8) + s[1]; } inline uint16_t Data::u16_aligned(const unsigned char* s) { efont_precondition((reinterpret_cast(s) & 1) == 0); return ntohs(*reinterpret_cast(s)); } inline int16_t Data::s16(const unsigned char* s) { return (int16_t) ((s[0] << 8) + s[1]); } inline int16_t Data::s16_aligned(const unsigned char* s) { efont_precondition((reinterpret_cast(s) & 1) == 0); return ntohs(*reinterpret_cast(s)); } inline uint32_t Data::u32(const unsigned char* s) { return ((unsigned) s[0] << 24) + (s[1] << 16) + (s[2] << 8) + s[3]; } inline uint32_t Data::u32_aligned16(const unsigned char* s) { efont_precondition((reinterpret_cast(s) & 1) == 0); return ((unsigned) u16_aligned(s) << 16) + u16_aligned(s + 2); } inline uint32_t Data::u32_aligned(const unsigned char* s) { efont_precondition((reinterpret_cast(s) & 3) == 0); return ntohl(*reinterpret_cast(s)); } inline int32_t Data::s32(const unsigned char* s) { return (int32_t) (((unsigned) s[0] << 24) + (s[1] << 16) + (s[2] << 8) + s[3]); } inline int32_t Data::s32_aligned16(const unsigned char* s) { efont_precondition((reinterpret_cast(s) & 1) == 0); return (int32_t) (((unsigned) u16_aligned(s) << 16) + u16_aligned(s + 2)); } inline int32_t Data::s32_aligned(const unsigned char* s) { efont_precondition((reinterpret_cast(s) & 3) == 0); return ntohl(*reinterpret_cast(s)); } inline uint16_t Data::u16(unsigned offset) const { if (offset + 1 >= static_cast(_str.length()) || offset + 1 == 0) throw Bounds(); else return u16_aligned(_str.udata() + offset); } inline int16_t Data::s16(unsigned offset) const { if (offset + 1 >= static_cast(_str.length()) || offset + 1 == 0) throw Bounds(); else return s16_aligned(_str.udata() + offset); } inline uint32_t Data::u32(unsigned offset) const { if (offset + 3 >= static_cast(_str.length()) || offset + 3 < 3) throw Bounds(); else return u32_aligned16(_str.udata() + offset); } inline int32_t Data::s32(unsigned offset) const { if (offset + 3 >= static_cast(_str.length()) || offset + 3 < 3) throw Bounds(); else return s32_aligned16(_str.udata() + offset); } inline uint8_t Data::operator[](int offset) const { return (*this)[unsigned(offset)]; } inline uint16_t Data::u16(int offset) const { return u16(unsigned(offset)); } inline int16_t Data::s16(int offset) const { return s16(unsigned(offset)); } inline uint32_t Data::u32(int offset) const { return u32(unsigned(offset)); } inline int32_t Data::s32(int offset) const { return s32(unsigned(offset)); } inline Data Data::substring(int left, int len) const noexcept { return Data(_str.substring(left, len)); } } // namespace Efont::OpenType } // namespace Efont #endif lcdf-typetools-2.108/include/efont/cff.hh0000644000175000017500000003202413423375327015244 00000000000000// -*- related-file-name: "../../libefont/cff.cc" -*- #ifndef EFONT_CFF_HH #define EFONT_CFF_HH #include #include class ErrorHandler; namespace Efont { class Type1Encoding; class Cff { public: class Dict; class IndexIterator; class Charset; class FDSelect; class FontParent; class Font; class CIDFont; class ChildFont; explicit Cff(const String& str, unsigned units_per_em, ErrorHandler* errh = 0); ~Cff(); bool ok() const { return _error >= 0; } int error() const { return _error; } const String &data_string() const { return _data_string; } const uint8_t *data() const { return _data; } int length() const { return _len; } int nfonts() const { return _name_index.size(); } PermString font_name(int i) const { return _name_index[i]; } FontParent* font(PermString = PermString(), ErrorHandler* = 0); enum { NSTANDARD_STRINGS = 391, MAX_SID = 64999 }; int max_sid() const { return NSTANDARD_STRINGS - 1 + _strings.size(); } int sid(PermString); String sid_string(int sid) const; PermString sid_permstring(int sid) const; int ngsubrs() const { return _gsubrs_index.nitems(); } Charstring *gsubr(int i); unsigned units_per_em() const { return _units_per_em; } enum DictOperator { oVersion = 0, oNotice = 1, oFullName = 2, oFamilyName = 3, oWeight = 4, oFontBBox = 5, oBlueValues = 6, oOtherBlues = 7, oFamilyBlues = 8, oFamilyOtherBlues = 9, oStdHW = 10, oStdVW = 11, oUniqueID = 13, oXUID = 14, oCharset = 15, oEncoding = 16, oCharStrings = 17, oPrivate = 18, oSubrs = 19, oDefaultWidthX = 20, oNominalWidthX = 21, oCopyright = 32 + 0, oIsFixedPitch = 32 + 1, oItalicAngle = 32 + 2, oUnderlinePosition = 32 + 3, oUnderlineThickness = 32 + 4, oPaintType = 32 + 5, oCharstringType = 32 + 6, oFontMatrix = 32 + 7, oStrokeWidth = 32 + 8, oBlueScale = 32 + 9, oBlueShift = 32 + 10, oBlueFuzz = 32 + 11, oStemSnapH = 32 + 12, oStemSnapV = 32 + 13, oForceBold = 32 + 14, oLanguageGroup = 32 + 17, oExpansionFactor = 32 + 18, oInitialRandomSeed = 32 + 19, oSyntheticBase = 32 + 20, oPostScript = 32 + 21, oBaseFontName = 32 + 22, oBaseFontBlend = 32 + 23, oROS = 32 + 30, oCIDFontVersion = 32 + 31, oCIDFontRevision = 32 + 32, oCIDFontType = 32 + 33, oCIDCount = 32 + 34, oUIDBase = 32 + 35, oFDArray = 32 + 36, oFDSelect = 32 + 37, oFontName = 32 + 38, oLastOperator = oFontName }; enum DictType { tNone = 0, tSID, tFontNumber, tBoolean, tNumber, tOffset, tLocalOffset, tArray, tArray2, tArray3, tArray4, tArray5, tArray6, tPrivateType, tTypeMask = 0x7F, tPrivate = 0x80, tP = tPrivate }; static const char * const operator_names[]; static const int operator_types[]; class IndexIterator { public: IndexIterator() : _offset(0), _last_offset(0), _offsize(-1) { } IndexIterator(const uint8_t *, int, int, ErrorHandler * = 0, const char *index_name = "INDEX"); int error() const { return (_offsize < 0 ? _offsize : 0); } typedef bool (IndexIterator::*unspecified_bool_type)() const; bool live() const { return _offset < _last_offset; } operator unspecified_bool_type() const { return live() ? &IndexIterator::live : 0; } int nitems() const; inline const uint8_t *operator*() const; inline const uint8_t *operator[](int) const; const uint8_t *index_end() const; void operator++() { _offset += _offsize; } void operator++(int) { ++(*this); } private: const uint8_t *_contents; const uint8_t *_offset; const uint8_t *_last_offset; int _offsize; inline uint32_t offset_at(const uint8_t *) const; }; private: String _data_string; const uint8_t *_data; int _len; int _error; Vector _name_index; IndexIterator _top_dict_index; IndexIterator _strings_index; mutable Vector _strings; mutable HashMap _strings_map; IndexIterator _gsubrs_index; Vector _gsubrs_cs; Vector _fonts; unsigned _units_per_em; int parse_header(ErrorHandler *); enum { HEADER_SIZE = 4 }; }; class Cff::Dict { public: Dict(); Dict(Cff *, int pos, int dict_len, ErrorHandler * = 0, const char *dict_name = "DICT"); int assign(Cff *, int pos, int dict_len, ErrorHandler * = 0, const char *dict_name = "DICT"); bool ok() const { return _error >= 0; } int error() const { return _error; } int check(bool is_private, ErrorHandler * = 0, const char *dict_name = "DICT") const; bool has(DictOperator) const; inline bool has_first(DictOperator) const; bool xvalue(DictOperator, Vector &) const; bool xvalue(DictOperator, int *) const; bool xvalue(DictOperator, double *) const; bool value(DictOperator, Vector &) const; bool value(DictOperator, int *) const; bool value(DictOperator, double *) const; void unparse(ErrorHandler *, const char *) const; private: Cff *_cff; int _pos; Vector _operators; Vector _pointers; Vector _operands; int _error; }; class Cff::Charset { public: Charset() : _error(-1) { } Charset(const Cff *, int pos, int nglyphs, int max_sid, ErrorHandler * = 0); void assign(const Cff *, int pos, int nglyphs, int max_sid, ErrorHandler * = 0); int error() const { return _error; } int nglyphs() const { return _sids.size(); } int nsids() const { return _gids.size(); } inline int gid_to_sid(int gid) const; inline int sid_to_gid(int sid) const; private: Vector _sids; Vector _gids; int _error; void assign(const int *, int, int); int parse(const Cff *, int pos, int nglyphs, int max_sid, ErrorHandler *); }; class Cff::FDSelect { public: FDSelect() : _fds(0), _my_fds(false), _nglyphs(0), _error(-1) { } ~FDSelect(); void assign(const Cff *, int pos, int nglyphs, ErrorHandler * = 0); int error() const { return _error; } int nglyphs() const { return _nglyphs; } inline int gid_to_fd(int gid) const; private: const uint8_t *_fds; bool _my_fds; int _nglyphs; int _error; FDSelect(const FDSelect &); FDSelect &operator=(const FDSelect &); int parse(const Cff *, int pos, int nglyphs, ErrorHandler *); }; class Cff::FontParent : public CharstringProgram { public: FontParent(Cff* cff); bool ok() const { return _error >= 0; } int error() const { return _error; } int ngsubrs_x() const { return _cff->ngsubrs(); } int ngsubrs() const { return ngsubrs_x(); } Charstring *gsubr(int) const; int gsubr_bias() const; private: Cff* _cff; int _charstring_type; int _error; int _font_index; FontParent(const FontParent &); FontParent &operator=(const FontParent &); Charstring *charstring(const IndexIterator &, int) const; friend class Cff; friend class Cff::Font; friend class Cff::CIDFont; friend class Cff::ChildFont; }; class Cff::CIDFont : public Cff::FontParent { public: CIDFont(Cff* cff, PermString, const Dict &, ErrorHandler *); ~CIDFont(); PermString font_name() const { return _font_name; } void font_matrix(double[6]) const; int nglyphs() const { return _charstrings_index.nitems(); } PermString glyph_name(int) const; void glyph_names(Vector &) const; Charstring *glyph(int) const; Charstring *glyph(PermString) const; int glyphid(PermString) const; const CharstringProgram *child_program(int) const; bool dict_has(DictOperator) const; String dict_string(DictOperator) const; bool dict_value(DictOperator, double *) const; bool dict_xvalue(DictOperator, double, double *) const; bool dict_value(DictOperator, Vector &) const; private: PermString _font_name; Dict _top_dict; Dict _private_dict; Cff::Charset _charset; IndexIterator _charstrings_index; mutable Vector _charstrings_cs; Vector _child_fonts; Cff::FDSelect _fdselect; const Dict &dict_of(DictOperator) const; }; class Cff::ChildFont : public Cff::FontParent { public: ChildFont(Cff* cff, Cff::CIDFont *, int charstring_type, const Dict &, ErrorHandler * = 0); ~ChildFont(); bool ok() const { return _error >= 0; } int error() const { return _error; } PermString font_name() const { return _parent->font_name(); } void font_matrix(double m[6]) const { _parent->font_matrix(m); } inline bool cid() const; int nsubrs_x() const { return _subrs_index.nitems(); } int nsubrs() const { return nsubrs_x(); } Charstring *subr(int) const; int subr_bias() const; int nglyphs() const { return _parent->nglyphs(); } PermString glyph_name(int gi) const { return _parent->glyph_name(gi); } void glyph_names(Vector &v) const { _parent->glyph_names(v); } Charstring *glyph(int gi) const { return _parent->glyph(gi); } Charstring *glyph(PermString n) const { return _parent->glyph(n); } double global_width_x(bool) const; private: Cff::CIDFont *_parent; Dict _top_dict; Dict _private_dict; IndexIterator _subrs_index; mutable Vector _subrs_cs; double _default_width_x; double _nominal_width_x; ChildFont(const ChildFont &); // does not exist ChildFont &operator=(const ChildFont &); // does not exist Charstring *charstring(const IndexIterator &, int) const; friend class Cff::Font; }; class Cff::Font : public Cff::ChildFont { public: Font(Cff* cff, PermString, const Dict &, ErrorHandler *); ~Font(); PermString font_name() const { return _font_name; } void font_matrix(double[6]) const; int nglyphs() const { return _charstrings_index.nitems(); } PermString glyph_name(int) const; void glyph_names(Vector &) const; Charstring *glyph(int) const; Charstring *glyph(PermString) const; int glyphid(PermString) const; Type1Encoding *type1_encoding() const; Type1Encoding *type1_encoding_copy() const; bool dict_has(DictOperator) const; String dict_string(DictOperator) const; inline bool dict_value(DictOperator, double *) const; inline bool dict_value(DictOperator, Vector &) const; const Dict &top_dict() const { return _top_dict; } private: PermString _font_name; Cff::Charset _charset; IndexIterator _charstrings_index; mutable Vector _charstrings_cs; int _encoding_pos; int _encoding[256]; mutable Type1Encoding *_t1encoding; int parse_encoding(int pos, ErrorHandler *); int assign_standard_encoding(const int *standard_encoding); inline const Dict &dict_of(DictOperator) const; }; inline uint32_t Cff::IndexIterator::offset_at(const uint8_t *x) const { switch (_offsize) { case 0: return 0; case 1: return x[0]; case 2: return (x[0] << 8) | x[1]; case 3: return (x[0] << 16) | (x[1] << 8) | x[2]; default: return (x[0] << 24) | (x[1] << 16) | (x[2] << 8) | x[3]; } } inline const uint8_t *Cff::IndexIterator::operator*() const { assert(live()); return _contents + offset_at(_offset); } inline const uint8_t *Cff::IndexIterator::operator[](int which) const { assert(live() && _offset + which * _offsize <= _last_offset); return _contents + offset_at(_offset + which * _offsize); } inline int Cff::Charset::gid_to_sid(int gid) const { if (gid >= 0 && gid < _sids.size()) return _sids[gid]; else return -1; } inline int Cff::Charset::sid_to_gid(int sid) const { if (sid >= 0 && sid < _gids.size()) return _gids[sid]; else return -1; } inline int Cff::FDSelect::gid_to_fd(int gid) const { if (gid >= 0 && gid < _nglyphs) return _fds[gid]; else return -1; } inline bool Cff::Dict::has_first(DictOperator op) const { return _operators.size() && _operators[0] == op; } inline const Cff::Dict &Cff::Font::dict_of(DictOperator op) const { return (op >= 0 && op <= oLastOperator && (operator_types[op] & tP) ? _private_dict : _top_dict); } inline bool Cff::Font::dict_value(DictOperator op, double *val) const { return dict_of(op).value(op, val); } inline bool Cff::Font::dict_value(DictOperator op, Vector &val) const { return dict_of(op).value(op, val); } } #endif lcdf-typetools-2.108/include/efont/otfname.hh0000664000175000017500000001020112732752520016126 00000000000000// -*- related-file-name: "../../libefont/otfname.cc" -*- #ifndef EFONT_OTFNAME_HH #define EFONT_OTFNAME_HH #include #include // for ntohl() #include namespace Efont { namespace OpenType { class Name { public: Name(const String &, ErrorHandler * = 0); // default destructor bool ok() const { return _error >= 0; } int error() const { return _error; } enum NameID { N_COPYRIGHT = 0, N_FAMILY = 1, N_SUBFAMILY = 2, N_UNIQUEID = 3, N_FULLNAME = 4, N_VERSION = 5, N_POSTSCRIPT = 6, N_TRADEMARK = 7, N_MANUFACTURER = 8, N_DESIGNER = 9, N_DESCRIPTION = 10, N_VENDOR_URL = 11, N_DESIGNER_URL = 12, N_LICENSE_DESCRIPTION = 13, N_LICENSE_URL = 14, N_PREF_FAMILY = 16, N_PREF_SUBFAMILY = 17, N_MAC_COMPAT_FULLNAME = 18, N_SAMPLE_TEXT = 19, N_POSTSCRIPT_CID = 20 }; enum Platform { P_UNICODE = 0, P_MACINTOSH = 1, P_MICROSOFT = 3, E_MS_UNICODE_BMP = 1, E_MAC_ROMAN = 0, L_MS_ENGLISH_AMERICAN = 0x409 }; enum { HEADER_SIZE = 6, NAMEREC_SIZE = 12 }; typedef uint8_t namerecord_t[NAMEREC_SIZE]; typedef const namerecord_t *const_iterator; inline static int nameid(const namerecord_t &); inline static int platform(const namerecord_t &); inline static int encoding(const namerecord_t &); inline static int language(const namerecord_t &); inline const_iterator begin() const; inline const_iterator end() const; String name(const_iterator) const; String utf8_name(const_iterator) const; String english_name(int nameid) const; // check version string for backwards compatibility bool version_chaincontext_reverse_backtrack() const; struct PlatformPred { inline PlatformPred(int nameid, int platform = -1, int encoding = -1, int language = -1); inline bool operator()(const namerecord_t &) const; private: int _nameid, _platform, _encoding, _language; }; struct EnglishPlatformPred { EnglishPlatformPred(int nameid) : _nameid(nameid) { } inline bool operator()(const namerecord_t &) const; private: int _nameid; }; private: String _str; int _error; int parse_header(ErrorHandler *); }; inline int Name::nameid(const namerecord_t &nr) { return Data::u16_aligned(reinterpret_cast(&nr) + 6); } inline int Name::platform(const namerecord_t &nr) { return Data::u16_aligned(reinterpret_cast(&nr)); } inline int Name::encoding(const namerecord_t &nr) { return Data::u16_aligned(reinterpret_cast(&nr) + 2); } inline int Name::language(const namerecord_t &nr) { return Data::u16_aligned(reinterpret_cast(&nr) + 4); } inline Name::const_iterator Name::begin() const { return reinterpret_cast(_str.udata() + HEADER_SIZE); } inline Name::const_iterator Name::end() const { if (_error >= 0) { int count = Data::u16_aligned(_str.udata() + 2); return reinterpret_cast(_str.udata() + HEADER_SIZE + NAMEREC_SIZE * count); } else return reinterpret_cast(_str.udata() + HEADER_SIZE); } inline Name::PlatformPred::PlatformPred(int nid, int p, int e, int l) : _nameid(nid), _platform(p), _encoding(e), _language(l) { } inline bool Name::PlatformPred::operator()(const namerecord_t &i) const { return (_nameid == nameid(i)) && (_platform < 0 || _platform == platform(i)) && (_encoding < 0 || _encoding == encoding(i)) && (_language < 0 || _language == language(i)); } inline bool Name::EnglishPlatformPred::operator()(const namerecord_t &i) const { if (_nameid == nameid(i)) { int p = platform(i), e = encoding(i), l = language(i); return (p == P_MACINTOSH && e == E_MAC_ROMAN && l == 0) || (p == P_MICROSOFT && e == E_MS_UNICODE_BMP && l == L_MS_ENGLISH_AMERICAN); } else return false; } } // namespace Efont::OpenType } // namespace Efont #endif lcdf-typetools-2.108/include/efont/otfpost.hh0000664000175000017500000000323412732752520016203 00000000000000// -*- related-file-name: "../../libefont/otfpost.cc" -*- #ifndef EFONT_OTFPOST_HH #define EFONT_OTFPOST_HH #include #include namespace Efont { namespace OpenType { class Post { public: Post(const String &, ErrorHandler * = 0); // default destructor bool ok() const { return _error >= 0; } int error() const { return _error; } double italic_angle() const; bool is_fixed_pitch() const; inline int underline_position() const; inline int underline_thickness() const; inline uint32_t mem_type42(bool ismax) const; int nglyphs() const { return _nglyphs; } bool glyph_names(Vector &gnames) const; private: Data _str; int _error; uint32_t _version; int _nglyphs; Vector _extend_glyph_names; enum { HEADER_SIZE = 32, N_MAC_GLYPHS = 258 }; int parse_header(ErrorHandler *); }; inline int Post::underline_position() const { // NB: "This is the suggested distance of the top of the underline from // the baseline (negative values indicate below baseline). The PostScript // definition of this FontInfo dictionary key (the y coordinate of the // center of the stroke) is not used for historical reasons. The value of // the PostScript key may be calculated by subtracting half the // underlineThickness from the value of this field." -- OpenType spec return ok() ? _str.s16(8) : 0; } inline int Post::underline_thickness() const { return ok() ? _str.s16(10) : 0; } inline uint32_t Post::mem_type42(bool ismax) const { return ok() ? _str.u32(ismax ? 20 : 16) : 0; } }} #endif lcdf-typetools-2.108/include/efont/otfcmap.hh0000664000175000017500000000365312732752520016143 00000000000000// -*- related-file-name: "../../libefont/otfcmap.cc" -*- #ifndef EFONT_OTFCMAP_HH #define EFONT_OTFCMAP_HH #include #include #include namespace Efont { namespace OpenType { class Cmap { public: Cmap(const String &, ErrorHandler * = 0); // default destructor bool ok() const { return _error >= 0; } int error() const { return _error; } inline Glyph map_uni(uint32_t c) const; int map_uni(const Vector &in, Vector &out) const; inline void unmap_all(Vector > &ugp) const; private: String _str; int _error; int _ntables; mutable int _first_unicode_table; mutable Vector _table_error; enum { HEADER_SIZE = 4, ENCODING_SIZE = 8, HIBYTE_SUBHEADERS = 524 }; enum Format { F_BYTE = 0, F_HIBYTE = 2, F_SEGMENTED = 4, F_TRIMMED = 6, F_HIBYTE32 = 8, F_TRIMMED32 = 10, F_SEGMENTED32 = 12 }; enum { USE_FIRST_UNICODE_TABLE = -2 }; int parse_header(ErrorHandler *); int first_unicode_table() const { return _first_unicode_table; } int first_table(int platform, int encoding) const; int check_table(int t, ErrorHandler * = 0) const; Glyph map_table(int t, uint32_t, ErrorHandler * = 0) const; void dump_table(int t, Vector > &ugp, ErrorHandler * = 0) const; inline const uint8_t* table_data(int t) const; }; inline Glyph Cmap::map_uni(uint32_t c) const { return map_table(USE_FIRST_UNICODE_TABLE, c, ErrorHandler::default_handler()); } inline void Cmap::unmap_all(Vector > &ugp) const { dump_table(USE_FIRST_UNICODE_TABLE, ugp, ErrorHandler::default_handler()); } inline const uint8_t* Cmap::table_data(int t) const { const uint8_t* data = _str.udata(); return data + Data::u32_aligned(data + HEADER_SIZE + t * ENCODING_SIZE + 4); } }} #endif lcdf-typetools-2.108/include/efont/t1bounds.hh0000644000175000017500000000551713423375327016254 00000000000000// -*- related-file-name: "../../libefont/t1bounds.cc" -*- #ifndef EFONT_T1BOUNDS_HH #define EFONT_T1BOUNDS_HH #include #include namespace Efont { class CharstringBounds : public CharstringInterp { public: CharstringBounds(); CharstringBounds(const Transform&); CharstringBounds(const Transform&, const Vector& weight_vec); ~CharstringBounds() { } const Point& width() const { return _width; } double x_width() const { return _width.x; } bool bb_known() const { return KNOWN(_lb.x); } double bb_left() const { return _lb.x; } double bb_top() const { return _rt.y; } double bb_right() const { return _rt.x; } double bb_bottom() const { return _lb.y; } const Point& bb_bottom_left() const { return _lb; } const Point& bb_top_right() const { return _rt; } void act_width(int, const Point&); void act_line(int, const Point&, const Point&); void act_curve(int, const Point&, const Point&, const Point&, const Point&); inline void mark(const Point&); void clear(); bool char_bounds(const CharstringContext&, bool shift = true); void translate(double dx, double dy); inline Point transform(const Point& p) const; // output: [left, bottom, right, top] bool output(double bb[4], double& width, bool use_cur_width = false) const; static bool bounds(const CharstringContext&, double bounds[4], double& width); static bool bounds(const Transform&, const CharstringContext&, double bounds[4], double& width); private: Point _lb; Point _rt; Point _width; Transform _xf; Transform _nonfont_xf; const CharstringProgram* _last_xf_program; void set_xf(const CharstringProgram*); inline void xf_mark(const Point&); void xf_mark(const Bezier&); inline bool xf_inside(const Point&) const; inline bool xf_controls_inside(const Bezier&) const; }; inline void CharstringBounds::xf_mark(const Point& p) { if (!KNOWN(_lb.x)) _lb = _rt = p; if (p.x < _lb.x) _lb.x = p.x; else if (p.x > _rt.x) _rt.x = p.x; if (p.y < _lb.y) _lb.y = p.y; else if (p.y > _rt.y) _rt.y = p.y; } inline void CharstringBounds::mark(const Point& p) { xf_mark(p * _xf); } inline bool CharstringBounds::xf_inside(const Point& p) const { return p.x >= _lb.x && p.x <= _rt.x && p.y >= _lb.y && p.y <= _rt.y; } inline bool CharstringBounds::xf_controls_inside(const Bezier& b) const { return xf_inside(b.point(1)) && xf_inside(b.point(2)); } inline Point CharstringBounds::transform(const Point& p) const { return p * _xf; } } #endif lcdf-typetools-2.108/include/efont/afm.hh0000664000175000017500000000257012732752520015252 00000000000000// -*- related-file-name: "../../libefont/afm.cc" -*- #ifndef EFONT_AFM_HH #define EFONT_AFM_HH #include class Slurper; class Filename; class ErrorHandler; namespace Efont { class AfmParser; struct AfmMetricsXt: public MetricsXt { Vector opening_comments; PermString notice; PermString encoding_scheme; PermString kind() const { return "AFM"; } }; class AfmReader { public: static Metrics *read(const Filename &, ErrorHandler *); static Metrics *read(Slurper &, ErrorHandler *); private: Metrics *_afm; AfmMetricsXt *_afm_xt; AfmParser &_l; ErrorHandler *_errh; mutable bool _composite_warned; mutable bool _metrics_sets_warned; mutable int _y_width_warned; void lwarning(const char *, ...) const; void lerror(const char *, ...) const; void composite_warning() const; void metrics_sets_warning() const; void y_width_warning() const; void no_match_warning(const char *context = 0) const; double &fd(int i) { return _afm->fd(i); } GlyphIndex find_err(PermString, const char *) const; void read_char_metric_data() const; void read_char_metrics() const; void read_kerns() const; void read_composites() const; bool read(); AfmReader(AfmParser &, Metrics *, AfmMetricsXt *, ErrorHandler *); }; } #endif lcdf-typetools-2.108/include/efont/t1rw.hh0000664000175000017500000001043412732752520015402 00000000000000// -*- related-file-name: "../../libefont/t1rw.cc" -*- #ifndef EFONT_T1RW_HH #define EFONT_T1RW_HH #include #include #include namespace Efont { class Type1Reader { public: Type1Reader(); virtual ~Type1Reader(); int get_data(unsigned char *, int); virtual int more_data(unsigned char *, int) = 0; virtual bool preserve_whitespace() const { return false; } void switch_eexec(bool, unsigned char *, int); virtual void set_charstring_definer(PermString); bool next_line(StringAccum &); bool was_charstring() const { return _charstring_len > 0; } int charstring_start() const { return _charstring_start; } int charstring_length() const { return _charstring_len; } private: enum { DATA_SIZE = 1024 }; unsigned char *_data; int _len; int _pos; PermString _charstring_definer; int _charstring_start; int _charstring_len; int _ungot; int _crlf; bool _eexec; bool _binary_eexec; int _r; Type1Reader(const Type1Reader &); Type1Reader &operator=(const Type1Reader &); int more_data(); inline int eexec(int); int ascii_eexec_get(); inline int get_base(); inline int get(); void start_eexec(int ascii_chars); bool test_charstring(StringAccum &); static unsigned char xvalue_store[]; static unsigned char *xvalue; static void static_initialize(); }; class Type1PFAReader : public Type1Reader { FILE *_f; public: Type1PFAReader(FILE *); int more_data(unsigned char *, int); }; class Type1PFBReader : public Type1Reader { FILE *_f; bool _binary; int _left; public: Type1PFBReader(FILE *); int more_data(unsigned char *, int); bool preserve_whitespace() const; }; class Type1SubsetReader : public Type1Reader { Type1Reader *_reader; int _left; public: Type1SubsetReader(Type1Reader *, int); int more_data(unsigned char *, int); bool preserve_whitespace() const; }; /***** * Writers **/ class Type1Writer { public: Type1Writer(); virtual ~Type1Writer(); bool eexecing() const { return _eexec; } inline void print(int); void print(const char *, int); inline Type1Writer &operator<<(char); inline Type1Writer &operator<<(unsigned char); Type1Writer &operator<<(int); Type1Writer &operator<<(double); virtual void flush(); virtual void switch_eexec(bool); virtual void print0(const unsigned char *, int) = 0; PermString charstring_start() const { return _charstring_start; } int lenIV() const { return _lenIV; } void set_charstring_start(PermString p) { _charstring_start = p; } void set_lenIV(int l) { _lenIV = l; } private: enum { BufSize = 1024 }; unsigned char *_buf; int _pos; bool _eexec; int _eexec_start; int _eexec_end; int _r; PermString _charstring_start; int _lenIV; void local_flush(); inline unsigned char eexec(int); Type1Writer(const Type1Writer &); Type1Writer &operator=(const Type1Writer &); }; class Type1PFAWriter: public Type1Writer { FILE *_f; int _hex_line; public: Type1PFAWriter(FILE *); ~Type1PFAWriter(); void switch_eexec(bool); void print0(const unsigned char *, int); }; class Type1PFBWriter: public Type1Writer { StringAccum _save; FILE *_f; bool _binary; public: Type1PFBWriter(FILE *); ~Type1PFBWriter(); void flush(); void switch_eexec(bool); void print0(const unsigned char *, int); }; inline void Type1Writer::print(int c) { if (_pos >= BufSize) local_flush(); _buf[_pos++] = c; } inline Type1Writer &operator<<(Type1Writer &w, const char *cc) { w.print(cc, strlen(cc)); return w; } inline Type1Writer &operator<<(Type1Writer &w, PermString p) { w.print(p.c_str(), p.length()); return w; } inline Type1Writer &operator<<(Type1Writer &w, const String &s) { w.print(s.data(), s.length()); return w; } inline Type1Writer &Type1Writer::operator<<(char c) { print((unsigned char)c); return *this; } inline Type1Writer &Type1Writer::operator<<(unsigned char c) { print(c); return *this; } } #endif lcdf-typetools-2.108/include/efont/psres.hh0000664000175000017500000000375612732752520015652 00000000000000// -*- related-file-name: "../../libefont/psres.cc" -*- #ifndef EFONT_PSRES_HH #define EFONT_PSRES_HH #include #include #include #include class Slurper; namespace Efont { class PsresDatabaseSection; class PsresDatabase { public: PsresDatabase(); ~PsresDatabase(); void add_psres_path(const char* path, const char* defaults, bool override); bool add_psres_file(Filename&, bool override); void add_database(PsresDatabase*, bool override); inline PsresDatabaseSection* section(PermString section) const; const String& value(PermString section, PermString key) const; const String& unescaped_value(PermString section, PermString key) const; Filename filename_value(PermString section, PermString key) const; private: HashMap _section_map; Vector _sections; PsresDatabaseSection* force_section(PermString); bool add_one_psres_file(Slurper&, bool override); void add_psres_directory(PermString); }; class PsresDatabaseSection { public: PsresDatabaseSection(PermString); PermString section_name() const { return _section_name; } void add_psres_file_section(Slurper&, PermString, bool); void add_section(PsresDatabaseSection*, bool override); const String& value(PermString key) { return value(_map[key]); } inline const String& unescaped_value(PermString key) const; Filename filename_value(PermString key); private: PermString _section_name; HashMap _map; Vector _directories; Vector _values; Vector _value_escaped; const String& value(int index); }; inline PsresDatabaseSection* PsresDatabase::section(PermString n) const { return _sections[_section_map[n]]; } inline const String& PsresDatabaseSection::unescaped_value(PermString key) const { assert(!_value_escaped[_map[key]]); return _values[_map[key]]; } } #endif lcdf-typetools-2.108/include/efont/afmw.hh0000664000175000017500000000076012732752520015440 00000000000000#ifndef EFONT_AFMW_HH #define EFONT_AFMW_HH #include #include namespace Efont { class AfmWriter { public: static void write(Metrics *, FILE *); private: Metrics *_m; AfmMetricsXt *_afm_xt; FILE *_f; void write_prologue() const; void write_char_metric_data(GlyphIndex, int) const; void write_kerns() const; void write(); double fd(int i) const { return _m->fd(i); } AfmWriter(Metrics *, FILE *); }; } #endif lcdf-typetools-2.108/include/efont/pairop.hh0000664000175000017500000000547612732752520016011 00000000000000// -*- related-file-name: "../../libefont/pairop.cc" -*- #ifndef PAIROP_HH #define PAIROP_HH #include /* get GlyphIndex */ namespace Efont { enum PairOpDefs { opNoop = -1, opLigature = -2, opLigSimple = 0, opLigSaveLeft = 1, opLigSaveRight = 2, opLigPast1 = 4, opLigPast2 = 8, opAllblock = 0 }; typedef int PairOpIndex; class PairOp { public: PairOp() { } inline PairOp(GlyphIndex l, GlyphIndex r, int v, PairOpIndex nl); inline PairOp(GlyphIndex l, GlyphIndex r, GlyphIndex x, int kind, PairOpIndex nl); void noopify() { _val = opNoop; } void set_value(int val) { _val = val; } inline void set_next(PairOpIndex); bool is_lig() const { return _val <= opLigature; } bool is_kern() const { return _val >= 0; } bool is_noop() const { return _val == opNoop; } int lig_kind() const { assert(is_lig()); return -_val+opLigature; } GlyphIndex left() const { return _left; } GlyphIndex right() const { return _right; } GlyphIndex result() const { assert(is_lig()); return _result; } int value() const { return _val; } PairOpIndex next_left() const { return _next_left; } private: GlyphIndex _left; GlyphIndex _right; GlyphIndex _result; int _val; PairOpIndex _next_left; }; class PairProgram { public: PairProgram() : _reversed(false) { } PairProgram(const PairProgram &); void reserve_glyphs(int); PairOpIndex find_left(GlyphIndex gi) const { return _left_map[gi]; } PairOpIndex find(GlyphIndex leftgi, GlyphIndex rightgi) const; int op_count() const { return _op.size(); } const PairOp &op(PairOpIndex i) const { return _op[i]; } // Return true if it's a duplicate. bool add_kern(GlyphIndex, GlyphIndex, int); bool add_lig(GlyphIndex, GlyphIndex, GlyphIndex, int kind = opLigSimple); void set_reversed(bool r) { _reversed = r; } void unreverse(); void optimize(); void print() const; private: bool _reversed; Vector _left_map; Vector _op; inline const char *print_name(GlyphIndex) const; PairProgram &operator=(const PairProgram &) { assert(0); return *this; } }; inline PairOp::PairOp(GlyphIndex l, GlyphIndex r, int v, PairOpIndex nl) : _left(l), _right(r), _result(), _val(v), _next_left(nl) { } inline PairOp::PairOp(GlyphIndex l, GlyphIndex r, GlyphIndex x, int kind, PairOpIndex nl) : _left(l), _right(r), _result(x), _val(opLigature - kind), _next_left(nl) { } inline void PairOp::set_next(PairOpIndex nl) { _next_left = nl; } } #endif lcdf-typetools-2.108/include/efont/metrics.hh0000664000175000017500000001115712732752520016156 00000000000000// -*- related-file-name: "../../libefont/metrics.cc" -*- #ifndef EFONT_METRICS_HH #define EFONT_METRICS_HH #include #include #include #include #include namespace Efont { class MetricsXt; class Metrics { public: Metrics(); Metrics(PermString font_name, PermString full_name, const Metrics &); ~Metrics(); void use() { _uses++; } void unuse() { if (--_uses == 0) delete this; } // GLOBALS PermString font_name() const { return _font_name; } PermString family() const { return _family; } PermString full_name() const { return _full_name; } PermString weight() const { return _weight; } PermString version() const { return _version; } void set_font_name(PermString); void set_family(PermString s) { _family = s; } void set_full_name(PermString s) { _full_name = s; } void set_weight(PermString s) { _weight = s; } void set_version(PermString s) { _version = s; } // GLYPHS int nglyphs() const { return _names.size(); } PermString name(GlyphIndex gi) const { return _names[gi]; } GlyphIndex find(PermString n) const { return _name_map[n]; } int code(GlyphIndex gi) const { return _encoding.code(gi); } GlyphIndex find_code(int c) const { return _encoding.find_code(c); } void set_code(GlyphIndex gi, int c) { _encoding.set_code(gi, c); } GlyphIndex add_glyph(PermString); void reserve_glyphs(int); // DIMENSIONS double scale() const { return _scale; } void set_scale(double d) { _scale = d; } int nfd() const { return _fdv.size(); } int nkv() const { return _kernv.size(); } double fd(int i) const { return _fdv[i]; } double wd(int i) const { return _wdv[i]; } double lf(int i) const { return _lfv[i]; } double rt(int i) const { return _rtv[i]; } double tp(int i) const { return _tpv[i]; } double bt(int i) const { return _btv[i]; } double kv(int i) const { return _kernv[i]; } double &fd(int i) { return _fdv[i]; } double &wd(int i) { return _wdv[i]; } double &lf(int i) { return _lfv[i]; } double &rt(int i) { return _rtv[i]; } double &tp(int i) { return _tpv[i]; } double &bt(int i) { return _btv[i]; } double &kv(int i) { return _kernv[i]; } inline int add_kv(double d); void interpolate_dimens(const Metrics &, double, bool increment); // PAIR PROGRAM PairProgram *pair_program() { return &_pairp; } const PairProgram *pair_program() const { return &_pairp; } inline bool add_kern(GlyphIndex, GlyphIndex, int); inline bool add_lig(GlyphIndex, GlyphIndex, GlyphIndex, int = opLigSimple); // EXTENSIONS MetricsXt *find_xt(PermString name) const { return _xt[_xt_map[name]]; } void add_xt(MetricsXt *); private: PermString _font_name; PermString _family; PermString _full_name; PermString _weight; PermString _version; HashMap _name_map; Vector _names; Encoding8 _encoding; double _scale; Vector _fdv; Vector _wdv; Vector _lfv; Vector _rtv; Vector _tpv; Vector _btv; PairProgram _pairp; Vector _kernv; HashMap _xt_map; Vector _xt; unsigned _uses; }; class MetricsXt { public: MetricsXt() { } virtual ~MetricsXt() { } virtual PermString kind() const = 0; virtual void reserve_glyphs(int) { } }; enum FontDimensionDefs { fdCapHeight = 0, fdXHeight, fdAscender, fdDescender, fdItalicAngle, fdUnderlinePosition, fdUnderlineThickness, fdFontBBllx, fdFontBBlly, fdFontBBurx, fdFontBBury, fdStdHW, fdStdVW, fdLast }; inline bool Metrics::add_kern(GlyphIndex g1, GlyphIndex g2, int ki) { return _pairp.add_kern(g1, g2, ki); } inline bool Metrics::add_lig(GlyphIndex g1, GlyphIndex g2, GlyphIndex gr, int kind) { return _pairp.add_lig(g1, g2, gr, kind); } inline int Metrics::add_kv(double d) { int k = _kernv.size(); _kernv.push_back(d); return k; } } #endif lcdf-typetools-2.108/include/efont/amfm.hh0000664000175000017500000000716112732752520015430 00000000000000// -*- related-file-name: "../../libefont/amfm.cc" -*- #ifndef EFONT_AMFM_HH #define EFONT_AMFM_HH #include #include #include class Slurper; class Filename; class ErrorHandler; namespace Efont { class AfmParser; class MetricsFinder; class Type1Charstring; struct AmfmMaster { PermString font_name; PermString family; PermString full_name; PermString version; Vector weight_vector; bool loaded; Metrics *afm; AmfmMaster() : loaded(0), afm(0) { } }; struct AmfmPrimaryFont { Vector design_vector; Vector labels; PermString name; AmfmPrimaryFont *next; }; class AmfmMetrics { public: AmfmMetrics(MetricsFinder *); ~AmfmMetrics(); void use() { _uses++; } void unuse() { if (--_uses == 0) delete this; } bool sanity(ErrorHandler *) const; double fd(int i) const { return _fdv[i]; } double &fd(int i) { return _fdv[i]; } PermString font_name() const { return _font_name; } PermString directory() const { return _directory; } int naxes() const { return _naxes; } int nmasters() const { return _nmasters; } MultipleMasterSpace *mmspace() const { return _mmspace; } int primary_label_value(int, PermString) const; Metrics *interpolate(const Vector &design, const Vector &weight, ErrorHandler *); private: MetricsFinder *_finder; PermString _directory; Vector _fdv; PermString _font_name; PermString _family; PermString _full_name; PermString _weight; PermString _version; PermString _notice; Vector _opening_comments; PermString _encoding_scheme; Vector _weight_vector; int _nmasters; int _naxes; AmfmMaster *_masters; MultipleMasterSpace *_mmspace; AmfmPrimaryFont *_primary_fonts; Metrics *_sanity_afm; unsigned _uses; friend class AmfmReader; AmfmMetrics(const AmfmMetrics &) { assert(0); } AmfmMetrics &operator=(const AmfmMetrics &) { assert(0); return *this; } AmfmPrimaryFont *find_primary_font(const Vector &design) const; Metrics *master(int, ErrorHandler *); }; class AmfmReader { public: static AmfmMetrics *read(const Filename &, MetricsFinder *, ErrorHandler*); static AmfmMetrics *read(Slurper &, MetricsFinder *, ErrorHandler *); static void add_amcp_file(Slurper &, AmfmMetrics *, ErrorHandler *); private: typedef Vector NumVector; AmfmMetrics *_amfm; MetricsFinder *_finder; AfmParser &_l; MultipleMasterSpace *_mmspace; ErrorHandler *_errh; double &fd(int i) const { return _amfm->fd(i); } int naxes() const { return _amfm->_naxes; } int nmasters() const { return _amfm->_nmasters; } void check_mmspace(); void lwarning(const char *, ...) const; void lerror(const char *, ...) const; void no_match_warning(const char *context = 0) const; bool read_simple_array(Vector &) const; void read_positions() const; void read_normalize() const; void read_axis_types() const; void read_axis(int axis) const; void read_master(int master) const; void read_primary_fonts() const; void read_one_primary_font() const; void read_conversion_programs() const; bool read(); void read_amcp_file(); AmfmReader(AfmParser &, AmfmMetrics *, ErrorHandler *); }; } #endif lcdf-typetools-2.108/include/efont/t1interp.hh0000664000175000017500000001634312732752520016260 00000000000000// -*- related-file-name: "../../libefont/t1interp.cc" -*- #ifndef EFONT_T1INTERP_HH #define EFONT_T1INTERP_HH #include #include #include namespace Efont { class CharstringInterp { public: CharstringInterp(); CharstringInterp(const Vector &weight_vec); virtual ~CharstringInterp() { } int error() const { return _error; } int error_data() const { return _error_data; } static String error_string(int error, int error_data); inline String error_string() const; bool careful() const { return _careful; } void set_careful(bool c) { _careful = c; } bool done() const { return _done; } void set_done() { _done = true; } int size() const { return _sp; } double &at(unsigned i) { return _s[i]; } double &top(unsigned i = 0) { return _s[_sp - i - 1]; } double pop(unsigned n = 1) { _sp -= n; return _s[_sp]; } inline void push(double); void clear() { _sp = 0; } int ps_size() const { return _ps_sp; } double ps_at(unsigned i) const { return _ps_s[i]; } double ps_pop() { return _ps_s[--_ps_sp]; } inline void ps_push(double); void ps_clear() { _ps_sp = 0; } int subr_depth() const { return _subr_depth; } inline double &vec(Vector *, int); const Vector &weight_vector() const { return _weight_vector; } Vector *scratch_vector() { return &_scratch_vector; } const CharstringProgram *program() const { return _program; } inline Charstring *get_subr(int) const; inline Charstring *get_gsubr(int) const; inline Charstring *get_xsubr(bool g, int) const; inline Charstring *get_glyph(PermString) const; bool interpret(const CharstringProgram *, const Charstring *); inline bool interpret(const CharstringContext &); //virtual void init(const CharstringProgram *); bool error(int c) { return error(c, 0); } virtual bool error(int, int); virtual bool number(double); bool arith_command(int); bool vector_command(int); bool blend_command(); bool callsubr_command(); bool callgsubr_command(); inline bool callxsubr_command(bool g); bool mm_command(int, int); bool itc_command(int, int); const Point &left_sidebearing() const { return _lsb; } const Point ¤tpoint() const { return _cp; } void set_state_path() { _state = S_PATH; } virtual bool callothersubr_command(int, int); virtual bool type1_command(int); virtual bool type2_command(int, const uint8_t *, int *); virtual void act_sidebearing(int cmd, const Point &lsb); virtual void act_width(int cmd, const Point &width); virtual void act_default_width(int cmd); virtual void act_nominal_width_delta(int cmd, double delta); virtual void act_seac(int cmd, double asb, double adx, double ady, int bchar, int achar); virtual void act_line(int cmd, const Point &p0, const Point &p1); virtual void act_curve(int cmd, const Point &p0, const Point &p1, const Point &p2, const Point &p3); virtual void act_closepath(int cmd); virtual void act_flex(int cmd, const Point &p0, const Point &p1, const Point &p2, const Point &p3_4, const Point &p5, const Point &p6, const Point &p7, double flex_depth); virtual void act_hstem(int cmd, double y, double dy); virtual void act_vstem(int cmd, double x, double dx); virtual void act_hstem3(int cmd, double y0, double dy0, double y1, double dy1, double y2, double dy2); virtual void act_vstem3(int cmd, double x0, double dx0, double x1, double dx1, double x2, double dx2); virtual void act_hintmask(int cmd, const uint8_t *data, int nhints); typedef Charstring Cs; enum Errors { errOK = 0, errInternal = -1, errRunoff = -2, errUnimplemented = -3, errOverflow = -4, errUnderflow = -5, errVector = -6, errValue = -7, errSubr = -8, errGlyph = -9, errCurrentPoint = -10, errFlex = -11, errMultipleMaster = -12, errOpenStroke = -13, errLateSidebearing = -14, errOthersubr = -15, errOrdering = -16, errHintmask = -17, errSubrDepth = -18, errLastError = -18 }; enum { STACK_SIZE = 48, PS_STACK_SIZE = 24, MAX_SUBR_DEPTH = 10, SCRATCH_SIZE = 32 }; private: int _error; int _error_data; bool _done; bool _careful; double _s[STACK_SIZE]; int _sp; double _ps_s[PS_STACK_SIZE]; int _ps_sp; int _subr_depth; Vector _weight_vector; Vector _scratch_vector; Point _lsb; Point _cp; Point _seac_origin; const CharstringProgram *_program; enum State { S_INITIAL, S_SEAC, S_SBW, S_HSTEM, S_VSTEM, S_HINTMASK, S_IPATH, S_PATH }; State _state; bool _flex; // for processing Type 2 charstrings int _t2nhints; static double double_for_error; void initialize(); inline void ensure_weight_vector(); void fetch_weight_vector(); bool roll_command(); int type2_handle_width(int, bool); inline void actp_rmoveto(int, double, double); inline void actp_rlineto(int, double, double); void actp_rrcurveto(int, double, double, double, double, double, double); void actp_rrflex(int, double, double, double, double, double, double, double, double, double, double, double, double, double); }; inline String CharstringInterp::error_string() const { return error_string(_error, _error_data); } inline void CharstringInterp::push(double d) { if (_sp < STACK_SIZE) _s[_sp++] = d; else error(errOverflow); } inline void CharstringInterp::ps_push(double d) { if (_ps_sp < PS_STACK_SIZE) _ps_s[_ps_sp++] = d; else error(errOverflow); } inline double &CharstringInterp::vec(Vector *v, int i) { if (i < 0 || i >= v->size()) { error(errVector); return double_for_error; } else return v->at_u(i); } inline Charstring *CharstringInterp::get_subr(int n) const { return _program ? _program->subr(n) : 0; } inline Charstring *CharstringInterp::get_gsubr(int n) const { return _program ? _program->gsubr(n) : 0; } inline Charstring *CharstringInterp::get_xsubr(bool g, int n) const { return _program ? _program->xsubr(g, n) : 0; } inline Charstring *CharstringInterp::get_glyph(PermString n) const { return _program ? _program->glyph(n) : 0; } inline void CharstringInterp::ensure_weight_vector() { if (!_weight_vector.size()) fetch_weight_vector(); } inline bool CharstringInterp::callxsubr_command(bool g) { return (g ? callgsubr_command() : callsubr_command()); } inline bool CharstringInterp::interpret(const CharstringContext &g) { return interpret(g.program, g.cs); } } #endif lcdf-typetools-2.108/include/efont/findmet.hh0000664000175000017500000000527612732752520016143 00000000000000// -*- related-file-name: "../../libefont/findmet.cc" -*- #ifndef EFONT_FINDMET_HH #define EFONT_FINDMET_HH #include #include #include class Filename; class ErrorHandler; namespace Efont { class Metrics; class AmfmMetrics; class PsresDatabase; class MetricsFinder { public: MetricsFinder() : _next(0), _prev(0) { } virtual ~MetricsFinder(); MetricsFinder *next() const { return _next; } void add_finder(MetricsFinder *); Metrics *find_metrics(PermString, ErrorHandler * = 0); AmfmMetrics *find_amfm(PermString, ErrorHandler * = 0); virtual Metrics *find_metrics_x(PermString, MetricsFinder *, ErrorHandler *); virtual AmfmMetrics *find_amfm_x(PermString, MetricsFinder *, ErrorHandler *); void record(Metrics *m); virtual void record(Metrics *, PermString); virtual void record(AmfmMetrics *); private: MetricsFinder *_next; MetricsFinder *_prev; MetricsFinder(const MetricsFinder &) { } MetricsFinder &operator=(const MetricsFinder &) { return *this; } protected: Metrics *try_metrics_file(const Filename &, MetricsFinder *, ErrorHandler *); AmfmMetrics *try_amfm_file(const Filename &, MetricsFinder *, ErrorHandler *); }; class CacheMetricsFinder: public MetricsFinder { public: CacheMetricsFinder(); ~CacheMetricsFinder(); Metrics *find_metrics_x(PermString, MetricsFinder *, ErrorHandler *); AmfmMetrics *find_amfm_x(PermString, MetricsFinder *, ErrorHandler *); void record(Metrics *, PermString); void record(AmfmMetrics *); void clear(); private: HashMap _metrics_map; Vector _metrics; HashMap _amfm_map; Vector _amfm; }; class InstanceMetricsFinder: public MetricsFinder { public: InstanceMetricsFinder(bool call_mmpfb = true); Metrics *find_metrics_x(PermString, MetricsFinder *, ErrorHandler *); private: bool _call_mmpfb; Metrics *find_metrics_instance(PermString, MetricsFinder *, ErrorHandler *); }; class PsresMetricsFinder: public MetricsFinder { public: PsresMetricsFinder(PsresDatabase *); Metrics *find_metrics_x(PermString, MetricsFinder *, ErrorHandler *); AmfmMetrics *find_amfm_x(PermString, MetricsFinder *, ErrorHandler *); private: PsresDatabase *_psres; }; class DirectoryMetricsFinder: public MetricsFinder { public: DirectoryMetricsFinder(PermString); Metrics *find_metrics_x(PermString, MetricsFinder *, ErrorHandler *); AmfmMetrics *find_amfm_x(PermString, MetricsFinder *, ErrorHandler *); private: PermString _directory; }; } #endif lcdf-typetools-2.108/include/efont/otfos2.hh0000644000175000017500000000461613423375327015730 00000000000000// -*- related-file-name: "../../libefont/otfos2.cc" -*- #ifndef EFONT_OTFOS2_HH #define EFONT_OTFOS2_HH #include #include #include namespace Efont { namespace OpenType { class Os2 { public: Os2(const Data &, ErrorHandler * = 0); // default destructor bool ok() const { return _error >= 0; } int error() const { return _error; } enum Offsets { O_AVGCHARWIDTH = 2, O_SUBSCRIPTXSIZE = 10, O_SUBSCRIPTYSIZE = 12, O_SUBSCRIPTXOFFSET = 14, O_SUBSCRIPTYOFFSET = 16, O_SUPERSCRIPTXSIZE = 18, O_SUPERSCRIPTYSIZE = 20, O_SUPERSCRIPTXOFFSET = 22, O_SUPERSCRIPTYOFFSET = 24, O_STRIKEOUTSIZE = 26, O_STRIKEOUTPOSITION = 28, O_VENDORID = 58, O_TYPOASCENDER = 68, O_TYPODESCENDER = 70, O_TYPOLINEGAP = 72, O_XHEIGHT = 86, O_CAPHEIGHT = 88, O_LOWEROPTICALPOINTSIZE = 96, O_UPPEROPTICALPOINTSIZE = 98 }; enum { HEADER_SIZE = 2 }; inline int16_t typo_ascender() const; inline int16_t typo_descender() const; inline int16_t typo_line_gap() const; inline int16_t x_height() const; inline int16_t cap_height() const; inline double lower_optical_point_size() const; inline double upper_optical_point_size() const; inline bool has_optical_point_size() const noexcept; inline String vendor_id() const noexcept; private: Data _data; int _error; int parse_header(ErrorHandler *); }; inline int16_t Os2::typo_ascender() const { return _data.s16(O_TYPOASCENDER); } inline int16_t Os2::typo_descender() const { return _data.s16(O_TYPODESCENDER); } inline int16_t Os2::typo_line_gap() const { return _data.s16(O_TYPOLINEGAP); } inline int16_t Os2::x_height() const { return _data.s16(O_XHEIGHT); } inline int16_t Os2::cap_height() const { return _data.s16(O_CAPHEIGHT); } inline double Os2::lower_optical_point_size() const { return _data.u16(O_LOWEROPTICALPOINTSIZE) / 20.; } inline double Os2::upper_optical_point_size() const { return _data.u16(O_UPPEROPTICALPOINTSIZE) / 20.; } inline bool Os2::has_optical_point_size() const noexcept { return _data.length() >= O_UPPEROPTICALPOINTSIZE + 2; } inline String Os2::vendor_id() const noexcept { return _data.substring(O_VENDORID, 4).string(); } }} #endif lcdf-typetools-2.108/include/efont/t1font.hh0000664000175000017500000001161212732752520015717 00000000000000// -*- related-file-name: "../../libefont/t1font.cc" -*- #ifndef EFONT_T1FONT_HH #define EFONT_T1FONT_HH #include #include class StringAccum; class ErrorHandler; namespace Efont { class Type1Item; class Type1Definition; class Type1Encoding; class Type1IncludedFont; class Type1Subr; class Type1Reader; class Type1Writer; class MultipleMasterSpace; class Type1Font : public CharstringProgram { public: Type1Font(Type1Reader &); ~Type1Font(); int read(Type1Reader &); bool ok() const; inline PermString font_name() const; void font_matrix(double[6]) const; int nitems() const { return _items.size(); } Type1Item *item(int i) const { return _items[i]; } void add_item(Type1Item *it) { _items.push_back(it); } void add_definition(int dict, Type1Definition *); void add_type1_encoding(Type1Encoding *); int nsubrs() const { return _subrs.size(); } Type1Charstring *subr(int) const; int nglyphs() const { return _glyphs.size(); } PermString glyph_name(int) const; Type1Charstring *glyph(int) const; Type1Charstring *glyph(PermString) const; void add_glyph(Type1Subr *); Type1Subr *subr_x(int i) const { return _subrs[i]; } bool set_subr(int, const Type1Charstring &, PermString definer = PermString()); bool remove_subr(int); void fill_in_subrs(); void renumber_subrs(const Vector &); // dangerous! Type1Subr *glyph_x(int i) const { return _glyphs[i]; } Type1Encoding *type1_encoding() const { return _encoding; } // note: the order is relevant enum Dict { dFont = 0, dF = dFont, dFontInfo = 1, dFI = dFontInfo, dPrivate = 2, dP = dPrivate, dBlend = 3, dB = dBlend, dBlendFontInfo = dB+dFI, dBFI = dBlendFontInfo, dBlendPrivate = dB+dP, dBP = dBlendPrivate, dLast }; Type1Definition *dict(int d, PermString s) const { return _dict[d][s]; } Type1Definition *dict(PermString s) const { return _dict[dF][s]; } Type1Definition *p_dict(PermString s) const { return _dict[dP][s]; } Type1Definition *b_dict(PermString s) const { return _dict[dB][s]; } Type1Definition *bp_dict(PermString s) const { return _dict[dBP][s];} Type1Definition *fi_dict(PermString s) const { return _dict[dFI][s];} typedef HashMap DictHashMap; inline DictHashMap::const_iterator dict_begin(int dict) const; inline DictHashMap::iterator dict_begin(int dict); int first_dict_item(int d) const { return _index[d]; } Type1Definition *ensure(Dict, PermString); void add_header_comment(const String &); MultipleMasterSpace *create_mmspace(ErrorHandler * = 0) const; MultipleMasterSpace *mmspace() const; void undo_synthetic(); void set_charstring_definer(PermString d) { _charstring_definer = d; } void write(Type1Writer &); // font skeletons static Type1Font *skeleton_make(PermString, const String &version = String()); static Type1Font *skeleton_make_copy(const Type1Font *, PermString, const Vector *xuid_extension); void skeleton_comments_end(); void skeleton_fontinfo_end(); void skeleton_fontdict_end(); void skeleton_private_end(); void skeleton_common_subrs(); // for experts only void set_item(int, Type1Item *); inline void set_dict(int dict, PermString, Type1Definition *); void uncache_defs(); private: mutable bool _cached_defs; bool _built; mutable PermString _font_name; Vector _items; HashMap *_dict; int _index[dLast]; int _dict_deltas[dLast]; Vector _subrs; Vector _glyphs; HashMap _glyph_map; PermString _charstring_definer; Type1Encoding *_encoding; mutable bool _cached_mmspace; mutable MultipleMasterSpace *_mmspace; Type1IncludedFont *_synthetic_item; Type1Font(PermString); Type1Font(const Type1Font &); Type1Font &operator=(const Type1Font &); void read_encoding(Type1Reader &, const char *); bool read_synthetic_font(Type1Reader &, const char *, StringAccum &); void cache_defs() const; void shift_indices(int, int); Type1Item *dict_size_item(int) const; int get_dict_size(int) const; void set_dict_size(int, int); }; inline Type1Font::DictHashMap::const_iterator Type1Font::dict_begin(int dict) const { return _dict[dict].begin(); } inline Type1Font::DictHashMap::iterator Type1Font::dict_begin(int dict) { return _dict[dict].begin(); } inline void Type1Font::set_dict(int dict, PermString name, Type1Definition *t1d) { _dict[dict].insert(name, t1d); } inline PermString Type1Font::font_name() const { if (!_cached_defs) cache_defs(); return _font_name; } } #endif lcdf-typetools-2.108/include/efont/t1cs.hh0000664000175000017500000002226712732752520015366 00000000000000// -*- related-file-name: "../../libefont/t1cs.cc" -*- #ifndef EFONT_T1CS_HH #define EFONT_T1CS_HH #include #include #include #include namespace Efont { // Allow unknown doubles to have some `fuzz' -- so if an unknown double // is a bit off from the canonical UNKDOUBLE value, we'll still recognize // it as unknown. (Useful for interpolation.) #define UNKDOUBLE -9.79797e97 #define MIN_KNOWN_DOUBLE -9.69696e97 #define KNOWN(d) ((d) >= MIN_KNOWN_DOUBLE) class CharstringProgram; class CharstringInterp; struct CharstringContext; class MultipleMasterSpace; class Type1Encoding; class Charstring { public: Charstring() { } virtual ~Charstring(); virtual bool process(CharstringInterp &) const = 0; enum Commands { cError = 0, cHstem = 1, cVstem = 3, cVmoveto = 4, cRlineto = 5, cHlineto = 6, cVlineto = 7, cRrcurveto = 8, cClosepath = 9, cCallsubr = 10, cReturn = 11, cEscape = 12, cHsbw = 13, cEndchar = 14, cBlend = 16, cHstemhm = 18, cHintmask = 19, cCntrmask = 20, cRmoveto = 21, cHmoveto = 22, cVstemhm = 23, cRcurveline = 24, cRlinecurve = 25, cVvcurveto = 26, cHhcurveto = 27, cShortint = 28, cCallgsubr = 29, cVhcurveto = 30, cHvcurveto = 31, cEscapeDelta = 32, cDotsection = 32 + 0, cVstem3 = 32 + 1, cHstem3 = 32 + 2, cAnd = 32 + 3, cOr = 32 + 4, cNot = 32 + 5, cSeac = 32 + 6, cSbw = 32 + 7, cStore = 32 + 8, cAbs = 32 + 9, cAdd = 32 + 10, cSub = 32 + 11, cDiv = 32 + 12, cLoad = 32 + 13, cNeg = 32 + 14, cEq = 32 + 15, cCallothersubr = 32 + 16, cPop = 32 + 17, cDrop = 32 + 18, cPut = 32 + 20, cGet = 32 + 21, cIfelse = 32 + 22, cRandom = 32 + 23, cMul = 32 + 24, cSqrt = 32 + 26, cDup = 32 + 27, cExch = 32 + 28, cIndex = 32 + 29, cRoll = 32 + 30, cSetcurrentpoint = 32 + 33, cHflex = 32 + 34, cFlex = 32 + 35, cHflex1 = 32 + 36, cFlex1 = 32 + 37, cLastCommand = cFlex1 }; enum OthersubrCommands { othcFlexend = 0, othcFlexbegin = 1, othcFlexmiddle = 2, othcReplacehints = 3, othcCountercontrolpart = 12, othcCountercontrol = 13, othcMM1 = 14, othcMM2 = 15, othcMM3 = 16, othcMM4 = 17, othcMM6 = 18, othcITC_load = 19, othcITC_add = 20, othcITC_sub = 21, othcITC_mul = 22, othcITC_div = 23, othcITC_put = 24, othcITC_get = 25, othcITC_unknown = 26, othcITC_ifelse = 27, othcITC_random = 28 }; static String command_name(int); static const char * const command_names[]; static const char * const standard_encoding[256]; }; class Type1Charstring : public Charstring { public: Type1Charstring() { } inline Type1Charstring(const String &); // unencrypted Type1Charstring(int lenIV, const String &); // encrypted // default copy constructor // default destructor // default assignment operator inline const uint8_t *data() const; int length() const { return _s.length(); } operator String::unspecified_bool_type() const { return _s; } inline const String &data_string() const; inline String substring(int pos, int len) const; int first_caret_after(int pos) const; inline void assign(const String &); void prepend(const Type1Charstring &); void assign_substring(int pos, int len, const String &); bool process(CharstringInterp &) const; private: mutable String _s; mutable int _key; void decrypt() const; }; class Type2Charstring : public Charstring { public: Type2Charstring() { } inline Type2Charstring(const String &); // default copy constructor // default destructor // default assignment operator inline const uint8_t *data() const; int length() const { return _s.length(); } bool process(CharstringInterp &) const; private: String _s; }; struct CharstringContext { CharstringContext(const CharstringProgram *program_, const Charstring *cs_) : program(program_), cs(cs_) { } operator String::unspecified_bool_type() const { return cs != 0 ? &String::length : 0; } const CharstringProgram *program; const Charstring *cs; }; class CharstringProgram { public: explicit CharstringProgram(unsigned units_per_em); virtual ~CharstringProgram() { } virtual PermString font_name() const { return PermString(); } virtual void font_matrix(double[6]) const; unsigned units_per_em() const { return _units_per_em; } inline const CharstringProgram *program(int) const; virtual const CharstringProgram *child_program(int) const; bool parent_program() const { return _parent_program; } void set_parent_program(bool pp) { _parent_program = pp; } virtual int nsubrs() const { return 0; } virtual Charstring *subr(int) const { return 0; } virtual int subr_bias() const { return 0; } virtual int ngsubrs() const { return 0; } virtual Charstring *gsubr(int) const { return 0; } virtual int gsubr_bias() const { return 0; } inline int nxsubrs(bool g) const; inline Charstring *xsubr(bool g, int) const; inline int xsubr_bias(bool g) const; virtual int nglyphs() const { return 0; } virtual PermString glyph_name(int) const { return PermString(); } virtual void glyph_names(Vector &) const; virtual Charstring *glyph(int) const { return 0; } virtual Charstring *glyph(PermString) const { return 0; } inline CharstringContext glyph_context(int) const; inline CharstringContext glyph_context(PermString) const; virtual bool is_mm() const { return mmspace() != 0; } virtual MultipleMasterSpace *mmspace() const { return 0; } enum VectorType { VEC_WEIGHT = 0, VEC_NORM_DESIGN = 1, VEC_DESIGN = 2 }; virtual Vector *mm_vector(VectorType, bool writable) const; virtual Type1Encoding *type1_encoding() const { return 0; } virtual double global_width_x(bool is_nominal) const; private: bool _parent_program; uint16_t _units_per_em; }; enum Type1Defs { t1Warmup_ee = 4, t1R_ee = 55665, t1R_cs = 4330, t1C1 = 52845, t1C2 = 22719 }; inline Type1Charstring::Type1Charstring(const String &s) : Charstring(), _s(s), _key(-1) { } inline void Type1Charstring::assign(const String &s) { _s = s; _key = -1; } inline const uint8_t *Type1Charstring::data() const { if (_key >= 0) decrypt(); return reinterpret_cast(_s.data()); } inline const String &Type1Charstring::data_string() const { if (_key >= 0) decrypt(); return _s; } inline String Type1Charstring::substring(int pos, int len) const { if (_key >= 0) decrypt(); return _s.substring(pos, len); } inline bool operator==(const Type1Charstring &a, const Type1Charstring &b) { return a.data_string() == b.data_string(); } inline Type2Charstring::Type2Charstring(const String &s) : _s(s) { } inline const uint8_t *Type2Charstring::data() const { return reinterpret_cast(_s.data()); } inline int CharstringProgram::nxsubrs(bool g) const { return (g ? ngsubrs() : nsubrs()); } inline Charstring *CharstringProgram::xsubr(bool g, int i) const { return (g ? gsubr(i) : subr(i)); } inline int CharstringProgram::xsubr_bias(bool g) const { return (g ? gsubr_bias() : subr_bias()); } inline const CharstringProgram *CharstringProgram::program(int gi) const { return (_parent_program ? child_program(gi) : this); } inline CharstringContext CharstringProgram::glyph_context(int gi) const { if (!_parent_program) return CharstringContext(this, glyph(gi)); else if (const CharstringProgram *p = child_program(gi)) return CharstringContext(p, p->glyph(gi)); else return CharstringContext(0, 0); } inline CharstringContext CharstringProgram::glyph_context(PermString gn) const { return CharstringContext(this, glyph(gn)); } } #endif lcdf-typetools-2.108/include/efont/otfgsub.hh0000644000175000017500000003141113423375327016156 00000000000000// -*- related-file-name: "../../libefont/otfgsub.cc" -*- #ifndef EFONT_OTFGSUB_HH #define EFONT_OTFGSUB_HH #include #include namespace Efont { namespace OpenType { class GsubLookup; class Substitution; class Gsub { public: Gsub(const Data &, const Font *, ErrorHandler * = 0); // default destructor const ScriptList &script_list() const { return _script_list; } const FeatureList &feature_list() const { return _feature_list; } bool chaincontext_reverse_backtrack() const { return _chaincontext_reverse_backtrack; } int nlookups() const; GsubLookup lookup(unsigned) const; enum { HEADERSIZE = 10 }; private: ScriptList _script_list; FeatureList _feature_list; Data _lookup_list; bool _chaincontext_reverse_backtrack; }; class GsubLookup { public: GsubLookup(const Data &); int type() const { return _type; } uint16_t flags() const { return _d.u16(2); } void mark_out_glyphs(const Gsub &gsub, Vector &gmap) const; bool unparse_automatics(const Gsub &gsub, Vector &subs, const Coverage &limit) const; bool apply(const Glyph *, int pos, int n, Substitution &) const; enum { HEADERSIZE = 6, RECSIZE = 2, L_SINGLE = 1, L_MULTIPLE = 2, L_ALTERNATE = 3, L_LIGATURE = 4, L_CONTEXT = 5, L_CHAIN = 6, L_EXTENSION = 7, L_REVCHAIN = 8 }; private: Data _d; int _type; Data subtable(int i) const; }; class GsubSingle { public: GsubSingle(const Data &); // default destructor Coverage coverage() const noexcept; Glyph map(Glyph) const; void mark_out_glyphs(Vector &gmap) const; void unparse(Vector &subs, const Coverage &limit) const; bool apply(const Glyph *, int pos, int n, Substitution &) const; enum { HEADERSIZE = 6, FORMAT2_RECSIZE = 2 }; private: Data _d; }; class GsubMultiple { public: GsubMultiple(const Data &); // default destructor Coverage coverage() const noexcept; bool map(Glyph, Vector &) const; void mark_out_glyphs(Vector &gmap) const; void unparse(Vector &, bool alternate = false) const; bool apply(const Glyph *, int pos, int n, Substitution &, bool alternate = false) const; enum { HEADERSIZE = 6, RECSIZE = 2, SEQ_HEADERSIZE = 2, SEQ_RECSIZE = 2 }; private: Data _d; }; class GsubLigature { public: GsubLigature(const Data &); // default destructor Coverage coverage() const noexcept; bool map(const Vector &, Glyph &, int &) const; void mark_out_glyphs(Vector &gmap) const; void unparse(Vector &) const; bool apply(const Glyph *, int pos, int n, Substitution &) const; enum { HEADERSIZE = 6, RECSIZE = 2, SET_HEADERSIZE = 2, SET_RECSIZE = 2, LIG_HEADERSIZE = 4, LIG_RECSIZE = 2 }; private: Data _d; }; class GsubContext { public: GsubContext(const Data &); // default destructor Coverage coverage() const noexcept; void mark_out_glyphs(const Gsub &gsub, Vector &gmap) const; bool unparse(const Gsub &gsub, Vector &out_subs, const Coverage &limit) const; enum { F3_HSIZE = 6, SUBRECSIZE = 4 }; private: Data _d; static void subruleset_mark_out_glyphs(const Data &data, int nsub, int subtab_offset, const Gsub &gsub, Vector &gmap); static bool f1_unparse(const Data& data, int nsub, int subtab_offset, const Gsub& gsub, Vector& outsubs, Substitution prototype_sub); static bool f3_unparse(const Data &data, int nglyph, int glyphtab_offset, const Coverage &limit, int nsub, int subtab_offset, const Gsub &gsub, Vector &outsubs, const Substitution &prototype_sub); friend class GsubChainContext; }; class GsubChainContext { public: GsubChainContext(const Data &); // default destructor Coverage coverage() const noexcept; void mark_out_glyphs(const Gsub &gsub, Vector &gmap) const; bool unparse(const Gsub &gsub, Vector &subs, const Coverage &limit) const; enum { F1_HEADERSIZE = 6, F1_RECSIZE = 2, F1_SRS_HSIZE = 2, F1_SRS_RSIZE = 2, F3_HSIZE = 4, F3_INPUT_HSIZE = 2, F3_LOOKAHEAD_HSIZE = 2, F3_SUBST_HSIZE = 2 }; private: Data _d; bool f1_unparse(const Gsub &gsub, Vector &subs, const Coverage &limit) const; bool f3_unparse(const Gsub &gsub, Vector &subs, const Coverage &limit) const; }; class Substitution { public: Substitution(); Substitution(const Substitution &); // single substitution Substitution(Glyph in, Glyph out); // multiple substitution Substitution(Glyph in, const Vector &out, bool is_alternate = false); // ligature substitution Substitution(Glyph in1, Glyph in2, Glyph out); Substitution(const Vector &in, Glyph out); Substitution(int nin, const Glyph *in, Glyph out); // space Substitution(int nleft, int nin, int nout, int nright); ~Substitution(); Substitution &operator=(const Substitution &); bool context_in(const Coverage &) const; bool context_in(const GlyphSet &) const; // types inline operator bool() const; bool is_noop() const; inline bool is_single() const; inline bool is_multiple() const; inline bool is_alternate() const; inline bool is_ligature() const; inline bool is_simple_context() const; inline bool is_single_lcontext() const; inline bool is_single_rcontext() const; inline bool is_lcontext() const; inline bool is_rcontext() const; // extract data inline Glyph left_glyph() const; inline int left_nglyphs() const; inline Glyph *left_glyphptr(); inline const Glyph *left_glyphptr() const; inline Glyph in_glyph() const; inline Glyph in_glyph(int pos) const; inline bool in_glyphs(Vector &) const; inline int in_nglyphs() const; inline Glyph *in_glyphptr(); inline const Glyph *in_glyphptr() const; inline bool in_matches(int pos, Glyph) const; inline Glyph out_glyph() const; inline Glyph out_glyph(int pos) const; inline bool out_glyphs(Vector &) const; inline Glyph *out_glyphptr(); inline const Glyph *out_glyphptr() const; inline int out_nglyphs() const; inline Glyph right_glyph() const; inline Glyph *right_glyphptr(); inline const Glyph *right_glyphptr() const; bool all_in_glyphs(Vector &gs) const; bool all_out_glyphs(Vector &gs) const; // alter void add_outer_left(Glyph); void remove_outer_left(); Substitution in_out_append_glyph(Glyph) const; bool out_alter(const Substitution &, int) noexcept; void add_outer_right(Glyph); void remove_outer_right(); void unparse(StringAccum &, const Vector * = &debug_glyph_names) const; String unparse(const Vector * = &debug_glyph_names) const; private: enum { T_NONE = 0, T_GLYPH, T_GLYPHS, T_COVERAGE }; typedef union { Glyph gid; Glyph *gids; // first entry is a count Coverage *coverage; } Substitute; Substitute _left; Substitute _in; Substitute _out; Substitute _right; uint8_t _left_is; uint8_t _in_is; uint8_t _out_is; uint8_t _right_is; bool _alternate : 1; static void clear(Substitute &, uint8_t &); static void assign_space(Substitute &, uint8_t &, int); static void assign(Substitute &, uint8_t &, Glyph); static void assign(Substitute &, uint8_t &, int, const Glyph *); static void assign(Substitute &, uint8_t &, const Coverage &); static void assign(Substitute &, uint8_t &, const Substitute &, uint8_t); static void assign_append(Substitute &, uint8_t &, const Substitute &, uint8_t, const Substitute &, uint8_t); static void assign_append(Substitute &, uint8_t &, const Substitute &, uint8_t, Glyph); static bool substitute_in(const Substitute &, uint8_t, const Coverage &); static bool substitute_in(const Substitute &, uint8_t, const GlyphSet &); static Glyph extract_glyph(const Substitute &, uint8_t) noexcept; static Glyph extract_glyph(const Substitute &, int which, uint8_t) noexcept; static bool extract_glyphs(const Substitute &, uint8_t, Vector &, bool coverage_ok) noexcept; static Glyph *extract_glyphptr(const Substitute &, uint8_t) noexcept; static int extract_nglyphs(const Substitute &, uint8_t, bool coverage_ok) noexcept; static bool matches(const Substitute &, uint8_t, int pos, Glyph) noexcept; static void unparse_glyphids(StringAccum &, const Substitute &, uint8_t, const Vector *) noexcept; }; inline Substitution::Substitution() : _left_is(T_NONE), _in_is(T_NONE), _out_is(T_NONE), _right_is(T_NONE) { } /* Single 1: u16 format, offset coverage, u16 glyphdelta Single 2: u16 format, offset coverage, u16 count, glyph subst[] Multiple 1: u16 format, offset coverage, u16 count, offset sequence[]; sequence is: u16 count, glyph subst[] Alternate 1: u16 format, offset coverage, u16 count, offset alternates[]; alternate is: u16 count, glyph alts[] Ligature 1: u16 format, offset coverage, u16 count, offset sets[]; set is: u16 count, offset ligatures[]; ligature is: glyph result, u16 count, glyph components[] */ inline Substitution::operator bool() const { return !(_left_is == T_NONE && _in_is == T_NONE && _out_is == T_NONE && _right_is == T_NONE); } inline bool Substitution::is_single() const { return _left_is == T_NONE && _in_is == T_GLYPH && _out_is == T_GLYPH && _right_is == T_NONE; } inline bool Substitution::is_multiple() const { return _left_is == T_NONE && _in_is == T_GLYPH && _out_is == T_GLYPHS && _right_is == T_NONE && !_alternate; } inline bool Substitution::is_alternate() const { return _left_is == T_NONE && _in_is == T_GLYPH && _out_is == T_GLYPHS && _right_is == T_NONE && _alternate; } inline bool Substitution::is_ligature() const { return _left_is == T_NONE && _in_is == T_GLYPHS && _out_is == T_GLYPH && _right_is == T_NONE; } inline bool Substitution::is_simple_context() const { return _left_is != T_COVERAGE && (_in_is == T_GLYPH || _in_is == T_GLYPHS) && (_out_is == T_GLYPH || _out_is == T_GLYPHS) && _right_is != T_COVERAGE; } inline bool Substitution::is_single_lcontext() const { return _left_is == T_GLYPH && _in_is == T_GLYPH && _out_is == T_GLYPH && _right_is == T_NONE; } inline bool Substitution::is_single_rcontext() const { return _left_is == T_NONE && _in_is == T_GLYPH && _out_is == T_GLYPH && _right_is == T_GLYPH; } inline Glyph Substitution::left_glyph() const { return extract_glyph(_left, _left_is); } inline int Substitution::left_nglyphs() const { return extract_nglyphs(_left, _left_is, false); } inline Glyph Substitution::in_glyph() const { return extract_glyph(_in, _in_is); } inline Glyph Substitution::in_glyph(int which) const { return extract_glyph(_in, which, _in_is); } inline bool Substitution::in_glyphs(Vector &v) const { return extract_glyphs(_in, _in_is, v, true); } inline int Substitution::in_nglyphs() const { return extract_nglyphs(_in, _in_is, true); } inline bool Substitution::in_matches(int pos, Glyph g) const { return matches(_in, _in_is, pos, g); } inline Glyph Substitution::out_glyph() const { return extract_glyph(_out, _out_is); } inline Glyph Substitution::out_glyph(int which) const { return extract_glyph(_out, which, _out_is); } inline bool Substitution::out_glyphs(Vector &v) const { return extract_glyphs(_out, _out_is, v, false); } inline int Substitution::out_nglyphs() const { return extract_nglyphs(_out, _out_is, false); } inline Glyph Substitution::right_glyph() const { return extract_glyph(_right, _right_is); } inline const Glyph *Substitution::left_glyphptr() const { return extract_glyphptr(_left, _left_is); } inline Glyph *Substitution::left_glyphptr() { return extract_glyphptr(_left, _left_is); } inline const Glyph *Substitution::in_glyphptr() const { return extract_glyphptr(_in, _in_is); } inline Glyph *Substitution::in_glyphptr() { return extract_glyphptr(_in, _in_is); } inline const Glyph *Substitution::out_glyphptr() const { return extract_glyphptr(_out, _out_is); } inline Glyph *Substitution::out_glyphptr() { return extract_glyphptr(_out, _out_is); } inline const Glyph *Substitution::right_glyphptr() const { return extract_glyphptr(_right, _right_is); } inline Glyph *Substitution::right_glyphptr() { return extract_glyphptr(_right, _right_is); } inline StringAccum &operator<<(StringAccum &sa, const Substitution &sub) { sub.unparse(sa); return sa; } }} #endif lcdf-typetools-2.108/include/efont/t1mm.hh0000664000175000017500000000631312732752520015364 00000000000000// -*- related-file-name: "../../libefont/t1mm.cc" -*- #ifndef EFONT_T1MM_HH #define EFONT_T1MM_HH #include class ErrorHandler; namespace Efont { class Type1Font; class MultipleMasterSpace : public CharstringProgram { public: MultipleMasterSpace(PermString, int naxes, int nmasters); // default destructor typedef Vector NumVector; PermString font_name() const { return _font_name; } int naxes() const { return _naxes; } int nmasters() const { return _nmasters; } int axis(PermString) const; double axis_low(int) const; double axis_high(int) const; PermString axis_type(int a) const { return _axis_types[a]; } PermString axis_label(int a) const { return _axis_labels[a]; } inline PermString axis_abbreviation(int a) const; static PermString axis_abbreviation(PermString); const Type1Charstring &ndv() const { return _ndv; } const Type1Charstring &cdv() const { return _cdv; } void set_master_positions(const Vector &); void set_normalize(const Vector &, const Vector &); void set_axis_type(int, PermString); void set_axis_label(int, PermString); void set_ndv(const Type1Charstring &cs) { _ndv = cs; } void set_cdv(const Type1Charstring &cs) { _cdv = cs; } void set_design_vector(const NumVector &); void set_weight_vector(const NumVector &); bool check(ErrorHandler * = 0); bool check_intermediate(ErrorHandler * = 0); NumVector empty_design_vector() const; inline const NumVector &default_design_vector() const; bool set_design(NumVector &, int, double, ErrorHandler * = 0) const; bool set_design(NumVector &, PermString, double, ErrorHandler * = 0) const; inline const NumVector &default_weight_vector() const; bool design_to_norm_design(const NumVector &, NumVector &, ErrorHandler * = 0) const; bool design_to_weight(const NumVector &, NumVector &, ErrorHandler * = 0) const; NumVector *mm_vector(VectorType, bool writable) const; private: mutable bool _ok; PermString _font_name; int _naxes; int _nmasters; Vector _master_positions; Vector _normalize_in; Vector _normalize_out; Vector _axis_types; Vector _axis_labels; Type1Charstring _ndv; Type1Charstring _cdv; NumVector _default_design_vector; NumVector _default_weight_vector; mutable NumVector *_design_vector; mutable NumVector *_norm_design_vector; mutable NumVector *_weight_vector; bool error(ErrorHandler *, const char *, ...) const; MultipleMasterSpace(const MultipleMasterSpace &); MultipleMasterSpace &operator=(const MultipleMasterSpace &); bool normalize_vector(ErrorHandler *) const; bool convert_vector(ErrorHandler *) const; }; inline const Vector &MultipleMasterSpace::default_design_vector() const { return _default_design_vector; } inline const Vector &MultipleMasterSpace::default_weight_vector() const { return _default_weight_vector; } inline PermString MultipleMasterSpace::axis_abbreviation(int a) const { return axis_abbreviation(_axis_types[a]); } } #endif lcdf-typetools-2.108/include/efont/t1item.hh0000664000175000017500000001575612732752520015724 00000000000000// -*- related-file-name: "../../libefont/t1item.cc" -*- #ifndef EFONT_T1ITEM_HH #define EFONT_T1ITEM_HH #include #include namespace Efont { class Type1Reader; class Type1Writer; class CharstringInterp; class Type1Font; class Type1CopyItem; class Type1Subr; class Type1SubrGroupItem; class Type1Definition; class Type1Item { public: Type1Item() { } virtual ~Type1Item() { } virtual void gen(Type1Writer &) = 0; virtual Type1CopyItem *cast_copy() { return 0; } virtual Type1Subr *cast_subr() { return 0; } virtual Type1Definition *cast_definition() { return 0; } virtual Type1SubrGroupItem *cast_subr_group() { return 0; } private: Type1Item(const Type1Item &); Type1Item &operator=(const Type1Item &); }; class Type1NullItem : public Type1Item { public: Type1NullItem() { } void gen(Type1Writer &); }; class Type1CopyItem : public Type1Item { public: Type1CopyItem(const String &s) : _value(s) { } ~Type1CopyItem() { } const String &value() const { return _value; } int length() const { return _value.length(); } void set_value(const String &s) { _value = s; } void gen(Type1Writer &); Type1CopyItem *cast_copy() { return this; } private: String _value; }; class Type1EexecItem : public Type1Item { public: Type1EexecItem(bool on) : _eexec_on(on) { } void gen(Type1Writer &w); private: bool _eexec_on; }; class Type1Definition : public Type1Item { public: typedef Vector NumVector; Type1Definition(PermString, const String &, PermString); ~Type1Definition() { } static Type1Definition *make(StringAccum &, Type1Reader * = 0, bool force = false); static Type1Definition *make_string(PermString, const String &, PermString); static inline Type1Definition *make_literal(PermString, const String &, PermString); static inline Type1Definition *make(PermString, double, PermString); PermString name() const { return _name; } const String &value() const { return _val; } PermString definer() const { return _definer; } bool value_bool(bool &) const; bool value_int(int &) const; bool value_num(double &) const; bool value_string(String &) const; bool value_name(PermString &) const; bool value_numvec(NumVector &) const; bool value_numvec_vec(Vector &) const; bool value_normalize(Vector &in, Vector &out) const; bool value_namevec(Vector &) const; void set_bool(bool); void set_int(int); void set_num(double); void set_string(const String &); void set_name(PermString, bool name = true); void set_code(const char *s) { set_val(s); } void set_numvec(const NumVector &, bool executable = false); void set_numvec_vec(const Vector &); void set_normalize(const Vector &, const Vector &); void set_namevec(const Vector &, bool executable = true); void gen(Type1Writer &); void gen(StringAccum &); Type1Definition *cast_definition() { return this; } private: PermString _name; String _val; PermString _definer; static int slurp_string(StringAccum &, int, Type1Reader *); static int slurp_proc(StringAccum &, int, Type1Reader *); inline void set_val(const String &); inline void set_val(StringAccum &); }; class Type1Encoding : public Type1Item { public: Type1Encoding(); Type1Encoding(const Type1Encoding &); ~Type1Encoding(); void clear(); void unshare(); PermString operator[](int e) const { assert(e>=0&&e<256); return _v[e]; } PermString elt(int e) const { return (*this)[e]; } PermString operator[](unsigned char e) const { return _v[e]; } PermString elt(unsigned char e) const { return operator[](e); } inline void put(int e, PermString p); void set_definer(PermString s) { _definer = s; } static Type1Encoding *standard_encoding(); void gen(Type1Writer &); private: PermString *_v; Type1Encoding *_copy_of; PermString _definer; Type1Encoding(Type1Encoding *); Type1Encoding &operator=(const Type1Encoding &); }; class Type1Subr : public Type1Item { public: static Type1Subr *make(const char *, int, int cs_start, int cs_len, int lenIV); static Type1Subr *make_subr(int, const Type1Charstring &, PermString); static Type1Subr *make_glyph(PermString, const Type1Charstring &, PermString); bool is_subr() const { return !_name; } PermString name() const { return _name; } int subrno() const { return _subrno; } PermString definer() const { return _definer; } Type1Charstring &t1cs() { return _cs; } const Type1Charstring &t1cs() const { return _cs; } operator Type1Charstring &() { return _cs; } operator const Type1Charstring &() const { return _cs; } void gen(Type1Writer &); virtual Type1Subr *cast_subr() { return this; } private: PermString _name; int _subrno; PermString _definer; Type1Charstring _cs; static PermString cached_definer; Type1Subr(PermString, int, PermString, int, const String &); Type1Subr(PermString, int, PermString, const Type1Charstring &); }; class Type1SubrGroupItem : public Type1Item { public: Type1SubrGroupItem(Type1Font *, bool, const String &); Type1SubrGroupItem(const Type1SubrGroupItem &, Type1Font *); ~Type1SubrGroupItem() { } void set_end_text(const String &s) { _end_text = s; } void add_end_text(const String &); bool is_subrs() const { return _is_subrs; } const String &end_text() const { return _end_text; } void gen(Type1Writer &); Type1SubrGroupItem *cast_subr_group() { return this; } private: Type1Font *_font; bool _is_subrs; String _value; String _end_text; }; class Type1IncludedFont : public Type1Item { public: Type1IncludedFont(Type1Font *, int); ~Type1IncludedFont(); Type1Font *included_font() const { return _included_font; } void gen(Type1Writer &); private: Type1Font *_included_font; int _unique_id; }; inline Type1Definition *Type1Definition::make_literal(PermString n, const String &v, PermString d) { return new Type1Definition(n, v, d); } inline Type1Definition *Type1Definition::make(PermString n, double v, PermString d) { return new Type1Definition(n, String(v), d); } inline void Type1Definition::set_val(const String &v) { _val = v; } inline void Type1Definition::set_val(StringAccum &sa) { _val = sa.take_string(); } inline void Type1Encoding::put(int e, PermString glyph) { if (_copy_of) unshare(); assert(e >= 0 && e < 256); _v[e] = glyph; } } #endif lcdf-typetools-2.108/include/efont/encoding.hh0000664000175000017500000000110512732752520016266 00000000000000// -*- related-file-name: "../../libefont/encoding.cc" -*- #ifndef EFONT_ENCODING_HH #define EFONT_ENCODING_HH #include namespace Efont { typedef int GlyphIndex; class Encoding8 { Vector _codes; Vector _code_map; public: Encoding8() : _code_map(256, -1) { } void reserve_glyphs(int); int code(GlyphIndex gi) const { return _codes[gi]; } GlyphIndex find_code(int c) const { return _code_map[c]; } void set_code(GlyphIndex gi, int c) { _codes[gi] = c; _code_map[c] = gi; } }; } #endif lcdf-typetools-2.108/include/efont/ttfhead.hh0000664000175000017500000000147212732752520016126 00000000000000// -*- related-file-name: "../../libefont/ttfhead.cc" -*- #ifndef EFONT_TTFHEAD_HH #define EFONT_TTFHEAD_HH #include #include // for ntohl() #include namespace Efont { namespace OpenType { class Head { public: Head(const String &, ErrorHandler * = 0); // default destructor bool ok() const { return _error >= 0; } int error() const { return _error; } unsigned units_per_em() const; unsigned index_to_loc_format() const; private: Data _d; int _error; int parse_header(ErrorHandler *); }; inline unsigned Head::units_per_em() const { return (_error >= 0 ? _d.u16(18) : 0); } inline unsigned Head::index_to_loc_format() const { return (_error >= 0 ? _d.u16(50) : 0); } }} #endif lcdf-typetools-2.108/include/efont/otfgpos.hh0000644000175000017500000001502413423375327016170 00000000000000// -*- related-file-name: "../../libefont/otfgpos.cc" -*- #ifndef EFONT_OTFGPOS_HH #define EFONT_OTFGPOS_HH #include #include namespace Efont { namespace OpenType { class GposLookup; class Positioning; class Gpos { public: Gpos(const Data &, ErrorHandler * = 0); // default destructor const ScriptList &script_list() const { return _script_list; } const FeatureList &feature_list() const { return _feature_list; } int nlookups() const; GposLookup lookup(unsigned) const; enum { HEADERSIZE = 10 }; private: ScriptList _script_list; FeatureList _feature_list; Data _lookup_list; }; class GposLookup { public: GposLookup(const Data &); int type() const { return _type; } uint16_t flags() const { return _d.u16(2); } bool unparse_automatics(Vector &, ErrorHandler * = 0) const; enum { HEADERSIZE = 6, RECSIZE = 2, L_SINGLE = 1, L_PAIR = 2, L_CURSIVE = 3, L_MARKTOBASE = 4, L_MARKTOLIGATURE = 5, L_MARKTOMARK = 6, L_CONTEXT = 7, L_CHAIN = 8, L_EXTENSION = 9 }; private: Data _d; int _type; Data subtable(int i) const; }; class GposValue { public: static inline int size(uint16_t format); static inline int16_t xplacement(uint16_t format, const Data &); static inline int16_t yplacement(uint16_t format, const Data &); static inline int16_t xadvance(uint16_t format, const Data &); static inline int16_t yadvance(uint16_t format, const Data &); enum { F_XPLACEMENT = 0x0001, F_YPLACEMENT = 0x0002, F_XADVANCE = 0x0004, F_YADVANCE = 0x0008, F_XPLACEMENT_DEVICE = 0x0010, F_YPLACEMENT_DEVICE = 0x0020, F_XADVANCE_DEVICE = 0x0040, F_YADVANCE_DEVICE = 0x0080 }; private: static const int nibble_bitcount_x2[]; }; class GposSingle { public: GposSingle(const Data &); // default destructor Coverage coverage() const noexcept; void unparse(Vector &) const; enum { F2_HEADERSIZE = 8 }; private: Data _d; }; class GposPair { public: GposPair(const Data &); // default destructor Coverage coverage() const noexcept; void unparse(Vector &) const; enum { F1_HEADERSIZE = 10, F1_RECSIZE = 2, PAIRSET_HEADERSIZE = 2, PAIRVALUE_HEADERSIZE = 2, F2_HEADERSIZE = 16 }; private: Data _d; }; struct Position { Glyph g; int pdx, pdy; // placement int adx, ady; // advance inline Position(); inline Position(Glyph, uint16_t format, const Data &); inline Position(uint16_t format, const Data &); inline Position(Glyph, const Position &); inline Position(Glyph g, int pdx, int pdy, int adx, int ady); bool empty() const { return pdx == 0 && pdy == 0 && adx == 0 && ady == 0; } operator bool() const { return !empty(); } bool h_empty() const { return pdx == 0 && pdy == 0 && adx == 0; } bool placed() const { return pdx != 0 || pdy != 0; } void unparse(StringAccum &, const Vector * = 0) const; String unparse(const Vector * = 0) const; }; class Positioning { public: Positioning(); // single positioning inline Positioning(const Position &); // pair positioning inline Positioning(const Position &, const Position &); bool context_in(const Coverage &) const; bool context_in(const GlyphSet &) const; // types inline operator bool() const; inline bool is_single() const; inline bool is_pair() const; inline bool is_pairkern() const; // extract data const Position &left() const { return _left; } Glyph left_glyph() const { return _left.g; } const Position &right() const { return _right; } Glyph right_glyph() const { return _right.g; } inline void all_in_glyphs(Vector &gs) const; void unparse(StringAccum &, const Vector * = 0) const; String unparse(const Vector * = 0) const; private: Position _left; Position _right; }; inline int GposValue::size(uint16_t format) { return (nibble_bitcount_x2[format & 15] + nibble_bitcount_x2[(format>>4) & 15]); } inline int16_t GposValue::xplacement(uint16_t format, const Data &d) { if (format & F_XPLACEMENT) return d.s16(0); else return 0; } inline int16_t GposValue::yplacement(uint16_t format, const Data &d) { if (format & F_YPLACEMENT) return d.s16((format & F_XPLACEMENT ? 2 : 0)); else return 0; } inline int16_t GposValue::xadvance(uint16_t format, const Data &d) { if (format & F_XADVANCE) return d.s16(nibble_bitcount_x2[format & (F_XADVANCE - 1)]); else return 0; } inline int16_t GposValue::yadvance(uint16_t format, const Data &d) { if (format & F_YADVANCE) return d.s16(nibble_bitcount_x2[format & (F_YADVANCE - 1)]); else return 0; } inline Position::Position() : g(0) { } inline Position::Position(Glyph g_, uint16_t format, const Data &value) : g(g_), pdx(GposValue::xplacement(format, value)), pdy(GposValue::yplacement(format, value)), adx(GposValue::xadvance(format, value)), ady(GposValue::yadvance(format, value)) { } inline Position::Position(uint16_t format, const Data &value) : g(0), pdx(GposValue::xplacement(format, value)), pdy(GposValue::yplacement(format, value)), adx(GposValue::xadvance(format, value)), ady(GposValue::yadvance(format, value)) { } inline Position::Position(Glyph g_, const Position &p) : g(g_), pdx(p.pdx), pdy(p.pdy), adx(p.adx), ady(p.ady) { } inline Position::Position(Glyph g_, int pdx_, int pdy_, int adx_, int ady_) : g(g_), pdx(pdx_), pdy(pdy_), adx(adx_), ady(ady_) { } inline Positioning::Positioning(const Position &left) : _left(left) { } inline Positioning::Positioning(const Position &left, const Position &right) : _left(left), _right(right) { } inline Positioning::operator bool() const { return _left.g != 0; } inline bool Positioning::is_single() const { return _left.g != 0 && _right.g == 0; } inline bool Positioning::is_pair() const { return _left.g != 0 && _right.g != 0; } inline bool Positioning::is_pairkern() const { return _left.g != 0 && !_left.placed() && _right.g != 0 && _right.h_empty(); } inline void Positioning::all_in_glyphs(Vector &gs) const { gs.clear(); if (_left.g != 0) gs.push_back(_left.g); if (_right.g != 0) gs.push_back(_right.g); } }} #endif lcdf-typetools-2.108/include/efont/otf.hh0000644000175000017500000002707313423375327015306 00000000000000// -*- related-file-name: "../../libefont/otf.cc" -*- #ifndef EFONT_OTF_HH #define EFONT_OTF_HH #include #include class ErrorHandler; namespace Efont { namespace OpenType { class Post; class Name; typedef int Glyph; // 16-bit integer class Tag { public: Tag() : _tag(0U) { } explicit Tag(uint32_t tag) : _tag(tag) { } Tag(const char *name); Tag(const String &name); // default destructor static Tag head_tag() { return Tag(0x68656164U); } typedef bool (Tag::*unspecified_bool_type)() const; bool null() const { return _tag == 0; } operator unspecified_bool_type() const { return _tag != 0 ? &Tag::null : 0; } bool valid() const; uint32_t value() const { return _tag; } String text() const; static String langsys_text(Tag script, Tag langsys = Tag()); const uint8_t* table_entry(const uint8_t* table, int n, int entry_size) const; const char* script_description() const; const char* language_description() const; const char* feature_description() const; private: uint32_t _tag; }; inline hashcode_t hashcode(const Tag& t) { return t.value(); } class Font { public: Font(const String& str, ErrorHandler* errh = 0); // default destructor bool ok() const { return _error >= 0; } bool check_checksums(ErrorHandler* errh = 0) const; int error() const { return _error; } const String& data_string() const { return _str; } const uint8_t* data() const { return _str.udata(); } int length() const { return _str.length(); } unsigned units_per_em() const { return _units_per_em; } int ntables() const; bool has_table(Tag tag) const; String table(Tag tag) const; uint32_t table_checksum(Tag tag) const; Tag table_tag(int i) const; static uint32_t checksum(const uint8_t *, const uint8_t *); static uint32_t checksum(const String &); static Font make(bool truetype, const Vector& tags, const Vector& data); enum { HEADER_SIZE = 12, TABLE_DIR_ENTRY_SIZE = 16 }; private: String _str; int _error; unsigned _units_per_em; int parse_header(ErrorHandler*); }; class ScriptList { public: ScriptList() { } inline ScriptList(const String&, ErrorHandler* = 0); int assign(const String&, ErrorHandler* = 0); // default destructor bool ok() const { return _str.length() > 0; } int language_systems(Vector& scripts, Vector& langsys, ErrorHandler* = 0) const; int features(Tag script, Tag langsys, int& required_fid, Vector& fids, ErrorHandler* = 0, bool clear_fids = true) const; private: enum { SCRIPTLIST_HEADERSIZE = 2, SCRIPT_RECSIZE = 6, SCRIPT_HEADERSIZE = 4, LANGSYS_RECSIZE = 6, LANGSYS_HEADERSIZE = 6, FEATURE_RECSIZE = 2 }; String _str; int check_header(ErrorHandler*); int script_offset(Tag) const; int check_script(Tag, int, ErrorHandler*) const; int langsys_offset(Tag, Tag, ErrorHandler* = 0) const; }; class FeatureList { public: FeatureList() { } inline FeatureList(const String&, ErrorHandler* = 0); int assign(const String&, ErrorHandler* = 0); // default destructor bool ok() const { return _str.length() > 0; } Tag tag(int fid) const; String params(int fid, int length, ErrorHandler* = 0, bool old_style_offset = false) const; String size_params(int fid, const Name& name, ErrorHandler* = 0) const; int lookups(int fid, Vector& results, ErrorHandler* = 0, bool clear_results = true) const; int find(Tag, const Vector& fids) const; void filter(Vector& fids, const Vector& sorted_ftags) const; inline void filter(Vector& fids, Tag ftag) const; int lookups(const Vector& fids, Vector& results, ErrorHandler* = 0) const; int lookups(const Vector& required_fids, const Vector& fids, const Vector& sorted_ftags, Vector& results, ErrorHandler* = 0) const; int lookups(int required_fid, const Vector& fids, const Vector& sorted_ftags, Vector& results, ErrorHandler* = 0) const; int lookups(const ScriptList&, Tag script, Tag langsys, const Vector& sorted_ftags, Vector& results, ErrorHandler* = 0) const; private: enum { FEATURELIST_HEADERSIZE = 2, FEATURE_RECSIZE = 6, FEATURE_HEADERSIZE = 4, LOOKUPLIST_RECSIZE = 2 }; String _str; int check_header(ErrorHandler*); int script_offset(Tag) const; int langsys_offset(Tag, Tag, ErrorHandler* = 0) const; }; class Coverage { public: Coverage() noexcept; // empty coverage Coverage(Glyph first, Glyph last) noexcept; // range coverage Coverage(const Vector &gmap) noexcept; // used-bytemap coverage Coverage(const String &str, ErrorHandler *errh = 0, bool check = true) noexcept; // default destructor bool ok() const noexcept { return _str.length() > 0; } int size() const noexcept; bool has_fast_covers() const noexcept { return _str.length() > 0 && _str.data()[1] == T_X_BYTEMAP; } int coverage_index(Glyph) const noexcept; bool covers(Glyph g) const noexcept { return coverage_index(g) >= 0; } void unparse(StringAccum&) const noexcept; String unparse() const noexcept; class iterator { public: iterator() : _pos(0), _value(0) { } // private constructor // default destructor bool ok() const { return _pos < _str.length(); } operator bool() const { return ok(); } Glyph operator*() const { return _value; } Glyph value() const { return _value; } int coverage_index() const; void operator++(int); void operator++() { (*this)++; } bool forward_to(Glyph); // XXX should check iterators are of same type bool operator<(const iterator& o) { return _value < o._value; } bool operator<=(const iterator& o) { return _value <= o._value; } bool operator>=(const iterator& o) { return _value >= o._value; } bool operator>(const iterator& o) { return _value > o._value; } bool operator==(const iterator& o) { return _value == o._value; } bool operator!=(const iterator& o) { return _value != o._value; } private: String _str; int _pos; Glyph _value; friend class Coverage; iterator(const String &str, bool is_end); }; iterator begin() const { return iterator(_str, false); } iterator end() const { return iterator(_str, true); } Glyph operator[](int) const noexcept; enum { T_LIST = 1, T_RANGES = 2, T_X_BYTEMAP = 3, HEADERSIZE = 4, LIST_RECSIZE = 2, RANGES_RECSIZE = 6 }; private: String _str; int check(ErrorHandler*); }; Coverage operator&(const Coverage&, const Coverage&); bool operator<=(const Coverage&, const Coverage&); inline bool operator>=(const Coverage& a, const Coverage& b) { return b <= a; } class GlyphSet { public: GlyphSet(); GlyphSet(const GlyphSet&); ~GlyphSet(); inline bool covers(Glyph g) const; inline bool operator[](Glyph g) const; int change(Glyph, bool); void insert(Glyph g) { change(g, true); } void remove(Glyph g) { change(g, false); } GlyphSet& operator=(const GlyphSet&); private: enum { GLYPHBITS = 16, SHIFT = 8, MAXGLYPH = (1 << GLYPHBITS) - 1, UNSHIFT = GLYPHBITS - SHIFT, MASK = (1 << UNSHIFT) - 1, VLEN = (1 << SHIFT), VULEN = (1 << UNSHIFT) >> 5 }; uint32_t* _v[VLEN]; }; class ClassDef { public: ClassDef(const String&, ErrorHandler* = 0) noexcept; // default destructor bool ok() const { return _str.length() > 0; } int nclass() const noexcept; int lookup(Glyph) const noexcept; int operator[](Glyph g) const noexcept { return lookup(g); } void unparse(StringAccum&) const noexcept; String unparse() const noexcept; class class_iterator { public: // private constructor // default destructor bool ok() const { return _pos < _str.length(); } operator bool() const { return ok(); } Glyph operator*() const { return *_coviter; } Glyph value() const { return *_coviter; } int class_value() const { return _class; } void operator++(int); void operator++() { (*this)++; } // XXX should check iterators are of same type bool operator<(const class_iterator& o) { return _coviter < o._coviter; } bool operator<=(const class_iterator& o) { return _coviter <= o._coviter; } bool operator>=(const class_iterator& o) { return _coviter >= o._coviter; } bool operator>(const class_iterator& o) { return _coviter > o._coviter; } bool operator==(const class_iterator& o) { return _coviter == o._coviter; } bool operator!=(const class_iterator& o) { return _coviter != o._coviter; } private: String _str; int _pos; int _class; Coverage::iterator _coviter; friend class ClassDef; class_iterator(const String&, int, int, const Coverage::iterator&); void increment_class0(); enum { FIRST_POS = -1, LAST_POS = -2 }; }; // XXX does not work correctly for class 0 class_iterator begin(int c) const { return class_iterator(_str, 0, c, Coverage::iterator()); } class_iterator begin(int c, const Coverage& coverage) const { return class_iterator(_str, 0, c, coverage.begin()); } class_iterator end(int c) const { return class_iterator(_str, _str.length(), c, Coverage::iterator()); } enum { T_LIST = 1, T_RANGES = 2, LIST_HEADERSIZE = 6, LIST_RECSIZE = 2, RANGES_HEADERSIZE = 4, RANGES_RECSIZE = 6 }; private: String _str; int check(ErrorHandler*); }; extern Vector debug_glyph_names; inline bool operator==(Tag t1, uint32_t t2) { return t1.value() == t2; } inline bool operator!=(Tag t1, uint32_t t2) { return t1.value() != t2; } inline bool operator<(Tag t1, uint32_t t2) { return t1.value() < t2; } inline bool operator>(Tag t1, uint32_t t2) { return t1.value() > t2; } inline bool operator<=(Tag t1, uint32_t t2) { return t1.value() <= t2; } inline bool operator>=(Tag t1, uint32_t t2) { return t1.value() >= t2; } inline bool operator==(Tag t1, Tag t2) { return t1.value() == t2.value(); } inline bool operator!=(Tag t1, Tag t2) { return t1.value() != t2.value(); } inline bool operator<(Tag t1, Tag t2) { return t1.value() < t2.value(); } inline ScriptList::ScriptList(const String& str, ErrorHandler* errh) { assign(str, errh); } inline FeatureList::FeatureList(const String& str, ErrorHandler* errh) { assign(str, errh); } inline void FeatureList::filter(Vector& fids, Tag ftag) const { Vector tags; tags.push_back(ftag); filter(fids, tags); } inline bool GlyphSet::covers(Glyph g) const { if ((unsigned)g > MAXGLYPH) return false; else if (const uint32_t* u = _v[g >> SHIFT]) return (u[(g & MASK) >> 5] & (1 << (g & 0x1F))) != 0; else return false; } inline bool GlyphSet::operator[](Glyph g) const { return covers(g); } } // namespace Efont::OpenType } // namespace Efont #endif lcdf-typetools-2.108/include/efont/t1csgen.hh0000664000175000017500000000674512732752520016063 00000000000000// -*- related-file-name: "../../libefont/t1csgen.cc" -*- #ifndef EFONT_T1CSGEN_HH #define EFONT_T1CSGEN_HH #include #include namespace Efont { class Type1Font; class Type1CharstringGen { public: Type1CharstringGen(int precision = 5); int precision() const { return _precision; } void clear(); char *data() { return _ncs.data(); } const char *data() const { return _ncs.data(); } int length() const { return _ncs.length(); } void gen_number(double, int kind = 0); void gen_command(int); void gen_stack(CharstringInterp &, int for_cmd); void append_charstring(const String &); const Point ¤t_point(bool real) const { return (real ? _true : _false); } void gen_moveto(const Point &, bool closepath, bool always); inline String take_string(); Type1Charstring *output(); void output(Type1Charstring &); static String callsubr_string(int subr); private: StringAccum _ncs; int _precision; double _f_precision; Point _true; Point _false; enum State { S_INITIAL, S_GEN }; State _state; void gen_rational(int big_val, int divisor); bool gen_stem3_stack(CharstringInterp &interp); }; class Type1CharstringGenInterp : public CharstringInterp { public: Type1CharstringGenInterp(int precision); int precision() const { return _csgen.precision(); } void set_direct_hint_replacement(bool dhr) { _direct_hr = dhr; } void set_hint_replacement_storage(Type1Font *); int nhints() const { return _stem_hstem.size(); } double max_flex_height() const { return _max_flex_height; } bool had_flex() const { return _had_flex; } bool had_bad_flex() const { return _had_bad_flex; } bool had_hr() const { return _had_hr; } const Type1CharstringGen &csgen() const { return _csgen; } void act_width(int, const Point &); void act_seac(int, double, double, double, int, int); void act_hstem(int, double, double); void act_vstem(int, double, double); void act_hintmask(int, const unsigned char *, int); void act_line(int, const Point &, const Point &); void act_curve(int, const Point &, const Point &, const Point &, const Point &); void act_closepath(int); void act_flex(int, const Point &, const Point &, const Point &, const Point &, const Point &, const Point &, const Point &, double); void intermediate_output(Type1Charstring &out); void run(const CharstringContext &g, Type1Charstring &out); private: // output Type1CharstringGen _csgen; mutable Type1CharstringGen _hint_csgen; // current glyph Point _width; enum State { S_INITIAL, S_OPEN, S_CLOSED, S_SEAC }; State _state; // hints and hint replacement Vector _stem_pos; Vector _stem_width; Vector _stem_hstem; String _last_hints; bool _in_hr; bool _direct_hr; int _hr_firstsubr; Type1Font *_hr_storage; // Flex double _max_flex_height; bool _had_flex; bool _had_bad_flex; bool _had_hr; inline void gen_number(double, int = 0); inline void gen_command(int); void gen_sbw(bool hints_follow); String gen_hints(const unsigned char *, int) const; void swap_stem_hints(); }; inline String Type1CharstringGen::take_string() { String s = _ncs.take_string(); clear(); return s; } } #endif lcdf-typetools-2.108/include/efont/ttfcs.hh0000664000175000017500000000170012732752520015624 00000000000000// -*- related-file-name: "../../libefont/ttfcs.cc" -*- #ifndef EFONT_TTFCS_HH #define EFONT_TTFCS_HH #include #include #include namespace Efont { class TrueTypeBoundsCharstringProgram : public CharstringProgram { public: TrueTypeBoundsCharstringProgram(const OpenType::Font *); ~TrueTypeBoundsCharstringProgram(); void font_matrix(double[6]) const; int nglyphs() const; Charstring *glyph(int gi) const; PermString glyph_name(int gi) const; void glyph_names(Vector &) const; private: const OpenType::Font *_otf; int _nglyphs; int _nhmtx; bool _loca_long; OpenType::Data _loca; OpenType::Data _glyf; OpenType::Data _hmtx; mutable Vector _charstrings; mutable Vector _glyph_names; mutable bool _got_glyph_names; mutable Vector _unicodes; mutable bool _got_unicodes; }; } #endif lcdf-typetools-2.108/include/config.h0000644000175000017500000000163413423375327014473 00000000000000#ifndef LCDF_TYPETOOLS_CONFIG_H #define LCDF_TYPETOOLS_CONFIG_H 1 #include /* Allow compilation on Windows (thanks, Fabrice Popineau). */ #ifdef WIN32 # ifdef __MINGW32__ # include # else # include # endif #else # include # define CDECL /* nothing */ #endif #ifdef __cplusplus extern "C" { #endif /* Prototype strerror if necessary. */ #if !HAVE_STRERROR char *strerror(int errno); #endif /* Prototype strnlen if necessary. */ #if !HAVE_DECL_STRNLEN size_t strnlen(const char *s, size_t maxlen); #endif /* Prototype good_strtod if necessary. */ #if HAVE_BROKEN_STRTOD double good_strtod(const char *s, char **endptr); #endif #ifdef __cplusplus } /* Get rid of a possible inline macro under C++. */ # define inline inline /* Ignore `noexcept` if compiler is too old. */ #if __cplusplus < 201103L #define noexcept #endif #endif #endif /* LCDF_TYPETOOLS_CONFIG_H */ lcdf-typetools-2.108/include/lcdf/0000755000175000017500000000000013423377072014040 500000000000000lcdf-typetools-2.108/include/lcdf/point.hh0000644000175000017500000000676413423375327015450 00000000000000// -*- related-file-name: "../../liblcdf/point.cc" -*- #ifndef LCDF_POINT_HH #define LCDF_POINT_HH #include struct Point { double x; double y; Point() { } Point(double xx, double yy) : x(xx), y(yy) { } // Point(const Point &) use compiler default Point(const Point &p, double dx, double dy) : x(p.x + dx), y(p.y + dy) { } // ~Point() use compiler default inline double squared_length() const noexcept; inline double length() const noexcept; inline double magnitude() const noexcept; static inline double distance(const Point &, const Point &) noexcept; static inline double dot(const Point &, const Point &) noexcept; static Point midpoint(const Point &, const Point &) noexcept; inline double angle() const noexcept; void shift(double dx, double dy) { x += dx; y += dy; } inline Point shifted(double dx, double dy) const noexcept; Point rotated(double) const noexcept; inline Point normal() const noexcept; bool on_line(const Point &, const Point &, double) const noexcept; bool on_segment(const Point &, const Point &, double) const noexcept; inline Point &operator+=(const Point &) noexcept; inline Point &operator-=(const Point &) noexcept; inline Point &operator*=(double) noexcept; inline Point &operator/=(double) noexcept; // Point operator+(Point, const Point &); // Point operator-(Point, const Point &); // Point operator*(Point, double); // Point operator/(Point, double); // Point operator-(const Point &); // bool operator==(const Point &, const Point &); // bool operator!=(const Point &, const Point &); }; inline double Point::squared_length() const noexcept { return x*x + y*y; } inline double Point::length() const noexcept { return sqrt(x*x + y*y); } inline double Point::magnitude() const noexcept { return length(); } inline double Point::angle() const noexcept { return atan2(y, x); } inline Point Point::shifted(double dx, double dy) const noexcept { return Point(x + dx, y + dy); } inline Point Point::normal() const noexcept { double l = length(); return (l ? Point(x/l, y/l) : *this); } inline Point & Point::operator+=(const Point &p) noexcept { x += p.x; y += p.y; return *this; } inline Point & Point::operator-=(const Point &p) noexcept { x -= p.x; y -= p.y; return *this; } inline Point & Point::operator*=(double d) noexcept { x *= d; y *= d; return *this; } inline Point & Point::operator/=(double d) noexcept { x /= d; y /= d; return *this; } inline bool operator==(const Point &a, const Point &b) noexcept { return a.x == b.x && a.y == b.y; } inline bool operator!=(const Point &a, const Point &b) noexcept { return a.x != b.x || a.y != b.y; } inline Point operator+(Point a, const Point &b) noexcept { a += b; return a; } inline Point operator-(Point a, const Point &b) noexcept { a -= b; return a; } inline Point operator-(const Point &a) noexcept { return Point(-a.x, -a.y); } inline Point operator*(Point a, double scale) noexcept { a *= scale; return a; } inline Point operator*(double scale, Point a) noexcept { a *= scale; return a; } inline Point operator/(Point a, double scale) noexcept { a /= scale; return a; } inline double Point::distance(const Point &a, const Point &b) noexcept { return (a - b).length(); } inline double Point::dot(const Point &a, const Point &b) noexcept { return a.x*b.x + a.y*b.y; } #endif lcdf-typetools-2.108/include/lcdf/md5.h0000664000175000017500000000314312732752520014616 00000000000000/* -*- related-file-name: "../../liblcdf/md5.c" -*- * md5.h - MD5 Message-Digest Algorithm * Copyright (C) 1995, 1996, 1998, 1999 Free Software Foundation, Inc. * * according to the definition of MD5 in RFC 1321 from April 1992. * NOTE: This is *not* the same file as the one from glibc * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef LCDF_MD5_H #define LCDF_MD5_H #ifdef __cplusplus extern "C" { #endif #define MD5_DIGEST_SIZE 16 #define MD5_TEXT_DIGEST_SIZE 26 /* + 1 for the terminating NUL */ typedef struct { /* Hmm, should be private */ uint32_t A,B,C,D; uint32_t nblocks; unsigned char buf[64]; int count; int finalized; } MD5_CONTEXT; void md5_init(MD5_CONTEXT *ctx); void md5_update(MD5_CONTEXT *hd, const unsigned char *inbuf, size_t inlen); void md5_final(unsigned char digest[MD5_DIGEST_SIZE], MD5_CONTEXT *ctx); void md5_final_text(char *text_digest, MD5_CONTEXT *ctx); #ifdef __cplusplus } #endif #endif /* LCDF_MD5_H */ lcdf-typetools-2.108/include/lcdf/vector.hh0000664000175000017500000002130612732752520015604 00000000000000#ifndef LCDF_VECTOR_HH #define LCDF_VECTOR_HH #include #include #ifdef HAVE_NEW_HDR # include #elif defined(HAVE_NEW_H) # include #else static inline void *operator new(size_t, void *v) { return v; } #endif #if HAVE_VALGRIND && HAVE_VALGRIND_MEMCHECK_H # include #endif template class Vector { public: typedef T value_type; typedef T& reference; typedef const T& const_reference; typedef T* pointer; typedef const T* const_pointer; typedef const T& const_access_type; typedef int size_type; enum { RESERVE_GROW = (size_type) -1 }; typedef T* iterator; typedef const T* const_iterator; explicit Vector() : _l(0), _n(0), _capacity(0) { } explicit Vector(size_type n, const T &e) : _l(0), _n(0), _capacity(0) { resize(n, e); } // template ... Vector(const Vector &x); ~Vector(); Vector& operator=(const Vector&); Vector& assign(size_type n, const T& e = T()); // template ... // iterators iterator begin() { return _l; } const_iterator begin() const { return _l; } iterator end() { return _l + _n; } const_iterator end() const { return _l + _n; } // capacity size_type size() const { return _n; } void resize(size_type nn, const T& e = T()); size_type capacity() const { return _capacity; } bool empty() const { return _n == 0; } bool reserve(size_type n) { return reserve_and_push_back(n, 0); } // element access T &operator[](size_type i) { assert((unsigned) i < (unsigned) _n); return _l[i]; } const T &operator[](size_type i) const { assert((unsigned) i < (unsigned) _n); return _l[i]; } T& at(size_type i) { return operator[](i); } const T& at(size_type i) const { return operator[](i); } T& front() { return operator[](0); } const T& front() const { return operator[](0); } T& back() { return operator[](_n - 1); } const T& back() const { return operator[](_n - 1); } T& at_u(size_type i) { return _l[i]; } const T& at_u(size_type i) const { return _l[i]; } // modifiers inline void push_back(const T& x); inline void pop_back(); inline void push_front(const T& x); inline void pop_front(); iterator insert(iterator it, const T& x); inline iterator erase(iterator it); iterator erase(iterator a, iterator b); void swap(Vector& x); void clear() { erase(begin(), end()); } private: T *_l; size_type _n; size_type _capacity; void *velt(size_type i) const { return (void *)&_l[i]; } static void *velt(T *l, size_type i) { return (void *)&l[i]; } bool reserve_and_push_back(size_type n, const T *x); }; template inline void Vector::push_back(const T& x) { if (_n < _capacity) { #ifdef VALGRIND_MAKE_MEM_UNDEFINED VALGRIND_MAKE_MEM_UNDEFINED(velt(_n), sizeof(T)); #endif new(velt(_n)) T(x); ++_n; } else reserve_and_push_back(RESERVE_GROW, &x); } template inline void Vector::pop_back() { assert(_n > 0); --_n; _l[_n].~T(); #ifdef VALGRIND_MAKE_MEM_NOACCESS VALGRIND_MAKE_MEM_NOACCESS(&_l[_n], sizeof(T)); #endif } template inline typename Vector::iterator Vector::erase(iterator it) { return (it < end() ? erase(it, it + 1) : it); } template inline void Vector::push_front(const T& x) { insert(begin(), x); } template inline void Vector::pop_front() { erase(begin()); } template <> class Vector { public: typedef void* value_type; typedef void*& reference; typedef void* const& const_reference; typedef void** pointer; typedef void* const* const_pointer; typedef void* const_access_type; typedef int size_type; enum { RESERVE_GROW = (size_type) -1 }; typedef void** iterator; typedef void* const* const_iterator; explicit Vector() : _l(0), _n(0), _capacity(0) { } explicit Vector(size_type n, void* e) : _l(0), _n(0), _capacity(0) { resize(n, e); } Vector(const Vector &); ~Vector(); Vector &operator=(const Vector &); Vector &assign(size_type n, void* x = 0); // iterators iterator begin() { return _l; } const_iterator begin() const { return _l; } iterator end() { return _l + _n; } const_iterator end() const { return _l + _n; } // capacity size_type size() const { return _n; } void resize(size_type n, void* x = 0); size_type capacity() const { return _capacity; } bool empty() const { return _n == 0; } bool reserve(size_type n); // element access void*& operator[](size_type i) { assert(i>=0 && i<_n); return _l[i]; } void* operator[](size_type i) const { assert(i>=0 && i<_n); return _l[i]; } void*& at(size_type i) { return operator[](i); } void* at(size_type i) const { return operator[](i); } void*& front() { return operator[](0); } void* front() const { return operator[](0); } void*& back() { return operator[](_n - 1); } void* back() const { return operator[](_n - 1); } void*& at_u(size_type i) { return _l[i]; } void* at_u(size_type i) const { return _l[i]; } // modifiers inline void push_back(void* x); inline void pop_back(); inline void push_front(void* x); inline void pop_front(); iterator insert(iterator it, void* x); inline iterator erase(iterator it); iterator erase(iterator a, iterator b); void swap(Vector &x); void clear() { _n = 0; } private: void **_l; size_type _n; size_type _capacity; }; inline void Vector::push_back(void* x) { if (_n < _capacity || reserve(RESERVE_GROW)) { _l[_n] = x; _n++; } } inline void Vector::pop_back() { assert(_n > 0); --_n; #ifdef VALGRIND_MAKE_MEM_NOACCESS VALGRIND_MAKE_MEM_NOACCESS(&_l[_n], sizeof(void *)); #endif } inline Vector::iterator Vector::erase(Vector::iterator it) { return (it < end() ? erase(it, it + 1) : it); } inline void Vector::push_front(void* x) { insert(begin(), x); } inline void Vector::pop_front() { erase(begin()); } template class Vector: private Vector { typedef Vector Base; public: typedef T* value_type; typedef T*& reference; typedef T* const& const_reference; typedef T** pointer; typedef T* const* const_pointer; typedef T* const_access_type; typedef int size_type; enum { RESERVE_GROW = Base::RESERVE_GROW }; typedef T** iterator; typedef T* const* const_iterator; explicit Vector() : Base() { } explicit Vector(size_type n, T* x) : Base(n, (void *)x) { } Vector(const Vector& x) : Base(x) { } ~Vector() { } Vector& operator=(const Vector& x) { Base::operator=(x); return *this; } Vector& assign(size_type n, T* x = 0) { Base::assign(n, (void*)x); return *this; } // iterators const_iterator begin() const { return (const_iterator)(Base::begin()); } iterator begin() { return (iterator)(Base::begin()); } const_iterator end() const { return (const_iterator)(Base::end()); } iterator end() { return (iterator)(Base::end()); } // capacity size_type size() const { return Base::size(); } void resize(size_type n, T* x = 0) { Base::resize(n, (void*)x); } size_type capacity() const { return Base::capacity(); } bool empty() const { return Base::empty(); } bool reserve(size_type n) { return Base::reserve(n); } // element access T*& operator[](size_type i) { return (T*&)(Base::at(i)); } T* operator[](size_type i) const { return (T*)(Base::operator[](i)); } T*& at(size_type i) { return (T*&)(Base::operator[](i)); } T* at(size_type i) const { return (T*)(Base::at(i)); } T*& front() { return (T*&)(Base::front()); } T* front() const { return (T*)(Base::front()); } T*& back() { return (T*&)(Base::back()); } T* back() const { return (T*)(Base::back()); } T*& at_u(size_type i) { return (T*&)(Base::at_u(i)); } T* at_u(size_type i) const { return (T*)(Base::at_u(i)); } // modifiers void push_back(T* x) { Base::push_back((void*)x); } void pop_back() { Base::pop_back(); } void push_front(T* x) { Base::push_front((void*)x); } void pop_front() { Base::pop_front(); } iterator insert(iterator it, T* x) { return (iterator)Base::insert((void**)it, (void*)x); } iterator erase(iterator it) { return (iterator)Base::erase((void**)it); } iterator erase(iterator a, iterator b) { return (iterator)Base::erase((void**)a, (void**)b); } void swap(Vector& x) { Base::swap(x); } void clear() { Base::clear(); } }; #include #endif lcdf-typetools-2.108/include/lcdf/bezier.hh0000644000175000017500000000542113423375327015564 00000000000000// -*- related-file-name: "../../liblcdf/bezier.cc" -*- #ifndef LCDF_BEZIER_HH #define LCDF_BEZIER_HH #include #include #include class Bezier { public: Bezier() : _bb(-1) { } inline Bezier(Point p[4]) noexcept; inline Bezier(const Point &, const Point &, const Point &, const Point &) noexcept; const Point *points() const { return _p; } const Point &point(int i) const { assert(i>=0&&i<4); return _p[i]; } Point &mpoint(int i) { assert(i>=0&&i<4); _bb = -1; return _p[i]; } void set_point(int i, const Point &p) { mpoint(i) = p; } Point eval(double) const noexcept; bool is_flat(double) const noexcept; bool in_bb(const Point &, double) const noexcept; bool hit(const Point &, double) const noexcept; inline double bb_left() const noexcept; inline double bb_right() const noexcept; inline double bb_top() const noexcept; inline double bb_bottom() const noexcept; inline double bb_left_x() const noexcept; inline double bb_right_x() const noexcept; inline double bb_top_x() const noexcept; inline double bb_bottom_x() const noexcept; void halve(Bezier &, Bezier &) const noexcept; inline void segmentize(Vector &) const; void segmentize(Vector &, bool) const; static void fit(const Vector &, double, Vector &); private: Point _p[4]; mutable int _bb; void make_bb() const noexcept; inline void ensure_bb() const noexcept; double hit_recurse(const Point &, double, double, double, double, double) const noexcept; }; inline Bezier::Bezier(Point p[4]) noexcept : _bb(-1) { memcpy(_p, p, sizeof(Point) * 4); } inline Bezier::Bezier(const Point &p0, const Point &p1, const Point &p2, const Point &p3) noexcept { _p[0] = p0; _p[1] = p1; _p[2] = p2; _p[3] = p3; _bb = -1; } inline void Bezier::ensure_bb() const noexcept { if (_bb < 0) make_bb(); } inline double Bezier::bb_top_x() const noexcept { return _p[(_bb >> 4) & 3].y; } inline double Bezier::bb_left_x() const noexcept { return _p[(_bb >> 2) & 3].x; } inline double Bezier::bb_bottom_x() const noexcept { return _p[(_bb >> 6) & 3].y; } inline double Bezier::bb_right_x() const noexcept { return _p[(_bb >> 0) & 3].x; } inline double Bezier::bb_top() const noexcept { ensure_bb(); return bb_top_x(); } inline double Bezier::bb_left() const noexcept { ensure_bb(); return bb_left_x(); } inline double Bezier::bb_bottom() const noexcept { ensure_bb(); return bb_bottom_x(); } inline double Bezier::bb_right() const noexcept { ensure_bb(); return bb_right_x(); } inline void Bezier::segmentize(Vector &v) const { segmentize(v, v.size() == 0 || v.back() != _p[0]); } #endif lcdf-typetools-2.108/include/lcdf/error.hh0000664000175000017500000007766112732752520015452 00000000000000// -*- related-file-name: "../../liblcdf/error.cc" -*- #ifndef LCDF_ERROR_HH #define LCDF_ERROR_HH #include #ifndef __KERNEL__ # include #endif #include #if HAVE_ADDRESSABLE_VA_LIST # define VA_LIST_REF_T va_list * # define VA_LIST_DEREF(val) (*(val)) # define VA_LIST_REF(val) (&(val)) #else # define VA_LIST_REF_T va_list # define VA_LIST_DEREF(val) (val) # define VA_LIST_REF(val) (val) #endif #if __GNUC__ <= 3 # define ERRH_SENTINEL # define ERRH_NORETURN #else # define ERRH_SENTINEL __attribute__((sentinel)) # define ERRH_NORETURN __attribute__((noreturn)) #endif /** @class ErrorHandler * @brief Error reporting class. * * Report errors through ErrorHandler objects, which represent * error collectors and printers. ErrorHandlers are passed to configure() and * initialize() methods explicitly, as well as to write handlers; the * click_chatter() function calls ErrorHandler implicitly. * *

Cooked error messages

* * Most ErrorHandler interactions consist of a simple call like this: * @code * errh->error("not enough arguments (%d needed)", 5); * // prints something like "not enough arguments (5 needed)\n" * @endcode * * This function constructs an error message string from the format arguments, * annotates the string with a default error level (here, el_error), and * prints it. Alternate versions take a landmark specifying where the error * took place: * @code * errh->lwarning("file.click:2", "syntax error at '%s'", word.c_str()); * // prints something like "file.click:2: syntax error at 'foo'\n" * @endcode * *

Raw error messages

* * For finer control over error levels and annotations, construct an error * message string directly. An error message is a string consisting of one or * more lines. Each line begins with a set of optional textual @em * annotations. The following error message has a @em level annotation * determining how serious the error is (this one is critical, since * el_critical == 2), and a @em landmark annotation, which specifies where the * error took place (here, "x.click:1"): * * "<2>{l:x.click:1}syntax error" * * The default ErrorHandlers understand the level and landmark * annotations. Users can add other arbitrary annotations, which can be * useful to pass error metadata. A pair of braces ends the annotation area. * This example has one user annotation eoc, and a message area that * would be mistaken for an annotation were it not for the {}: * * "<2>{l:x.click:1}{eoc:520}{}{not:an annotation}" * *

Stacking handlers

* * Some ErrorHandlers stack on top of others, adding useful functionality like * automatic context description and prefixing. For example, * ContextErrorHandler can be used to print messages like "In function * 'xxx':". * @code * FileErrorHandler errh1(stderr); * ContextErrorHandler errh2(&errh1, "While counting to 2:"); * errh2.error("An error occurred."); * errh2.error("Another error occurred."); * // prints "While counting to 2:\n" * // " An error occurred.\n" * // " Another error occurred.\n" * @endcode */ class ErrorHandler { public: /** @brief Error level constants. * * Lower values represent more serious errors. Levels 0-7 correspond to * Linux's error levels. Negative levels request immediate exit; at user * level, the exit status is the absolute value of the * error level. */ enum Level { el_abort = -999, ///< Error level that triggers abort(). el_fatal = -1, ///< Fatal exit error level. /// Exit status equals -(level). el_emergency = 0, ///< Emergency error level: system is unusable. el_alert = 1, ///< Alert error level: action must be taken. el_critical = 2, ///< Error level for critical conditions. el_error = 3, ///< Error level for normal error conditions. el_warning = 4, ///< Error level for warning conditions. el_notice = 5, ///< Error level for normal, but significant /// conditions. el_info = 6, ///< Error level for informational messages. el_debug = 7 ///< Error level for debug messages. }; /** @brief Error level indicators. */ static const char e_abort[], e_fatal[], e_emergency[], e_alert[], e_critical[], e_error[], e_warning[], e_warning_annotated[], e_notice[], e_info[], e_debug[]; /** @brief Construct an ErrorHandler. */ ErrorHandler() : _nerrors(0) { } virtual ~ErrorHandler() { } /** @brief Initialize the ErrorHandler implementation. * @param errh default error handler * @return @a errh * * Call this function to initialize the ErrorHandler implementation. The * function installs the default conversions, creates the * silent_handler(), and installs @a errh as the default error handler * (see default_handler()). * * @note The @a errh object becomes the property of the ErrorHandler * implementation and must not be deleted. * (ErrorHandler::static_cleanup() will delete it.) Only the first call * to static_initialize() has any effect. */ static ErrorHandler *static_initialize(ErrorHandler *errh); /** @brief Tear down the ErrorHandler implementation. * * Deletes the internal ErrorHandlers and uninstalls default * conversions. */ static void static_cleanup(); /** @brief Return the default ErrorHandler. * @sa static_initialize() */ static ErrorHandler *default_handler() { return the_default_handler; } /** @brief Set the default ErrorHandler to @a errh. * @note @a errh becomes property of the ErrorHandler implementation, * and will be freed by static_cleanup(). However, any prior default * handler is @em not destroyed. Callers should delete the prior handler * when necessary. */ static void set_default_handler(ErrorHandler *errh); /** @brief Return the global silent ErrorHandler. */ static ErrorHandler *silent_handler() { return the_silent_handler; } static const int ok_result; ///< Equals 0, used for error levels /// <5> and above static const int error_result; ///< Equals -EINVAL, used for error /// levels <4> and below /** @brief Print a debug message (level el_debug). * * @a fmt and any following arguments are parsed as by format(), and the * resulting string is passed to xmessage(). */ void debug(const char *fmt, ...); /** @brief Print an informational message (level el_info). */ void message(const char *fmt, ...); /** @brief Print a warning message (level el_warning). * @return error_result * * The string "warning: " is prepended to every line of the message. */ int warning(const char *fmt, ...); /** @brief Print an error message (level el_error). * @return error_result */ int error(const char *fmt, ...); /** @brief Print a fatal error message (level el_fatal). * @return error_result * * Calling fatal() will cause the process to abort. */ void fatal(const char *fmt, ...) ERRH_NORETURN; /** @brief Print a debug message with a landmark annotation. */ void ldebug(const String &landmark, const char *fmt, ...); /** @brief Print an informational message with a landmark annotation. */ void lmessage(const String &landmark, const char *fmt, ...); /** @brief Print a warning message with a landmark annotation. */ int lwarning(const String &landmark, const char *fmt, ...); /** @brief Print an error message with a landmark annotation. */ int lerror(const String &landmark, const char *fmt, ...); /** @brief Print a fatal error message with a landmark annotation. */ void lfatal(const String &landmark, const char *fmt, ...) ERRH_NORETURN; /** @brief Print an annotated error message. * @return ok_result if the minimum error level was el_notice or higher, * otherwise error_result * * This function drives the virtual functions actually responsible for * error message decoration and printing. It passes @a str to decorate(), * separates the result into lines, calls emit() for each line, and calls * account() with the minimum error level of any line. * * Most users will call shorthand functions like error(), warning(), or * lmessage(), which add relevant annotations to the message. */ int xmessage(const String &str); /** @brief Print an error message, adding annotations. * @param anno annotations * @param str error message * * Shorthand for xmessage(combine_anno(@a str, @a anno)). */ int xmessage(const String &anno, const String &str) { return xmessage(combine_anno(str, anno)); } /** @brief Format and print an error message, adding annotations. * @param anno annotations * @param fmt error message format * @param val format arguments * * Shorthand for xmessage(@a anno, vformat(@a fmt, @a val)). */ int xmessage(const String &anno, const char *fmt, va_list val) { return xmessage(anno, vformat(fmt, val)); } /** @brief Print an error message, adding landmark and other annotations. * @param landmark landmark annotation * @param anno additional annotations * @param str error message * * Shorthand for xmessage(combine_anno(@a anno, make_landmark_anno(@a * landmark)), @a str). */ int xmessage(const String &landmark, const String &anno, const String &str) { return xmessage(combine_anno(anno, make_landmark_anno(landmark)), str); } /** @brief Format and print an error message, adding landmark and other * annotations. * @param landmark landmark annotation * @param anno additional annotations * @param fmt error message format * @param val format arguments * * Shorthand for xmessage(@a landmark, @a anno, vformat(@a fmt, @a * val)). */ int xmessage(const String &landmark, const String &anno, const char *fmt, va_list val) { return xmessage(landmark, anno, vformat(fmt, val)); } /** @brief Return the number of errors reported via this handler. * * An error is any message that contains at least one line with error * level 3 (#el_error) or below. * * @note The error count will also contain errors reported via stacked * handlers. For instance: * @code * SilentErrorHandler errh1; * PrefixErrorHandler errh2(&errh1, ""); * assert(errh1.nerrors() == 0); * errh2.error("blah"); * assert(errh1.nerrors() == 1); * @endcode * * @sa account, clear */ int nerrors() const { return _nerrors; } /** @brief Format an error string. * @param default_flags default ConversionFlags * @param fmt printf-like format string * @return formatted error string * * Formats an error string using printf-like % conversions. Conversions * include: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
\%d, \%iFormat an int as a * decimal string. Understands flags in #0- +, field widths * (including *), and precisions.
\%hd, \%ld, \%lld, * \%zdFormat a short, long, long * long, or size_t.
\%^16d, \%^32d, \%^64dFormat a 16-, 32-, or 64-bit integer.
\%o, \%u, \%x, * \%XFormat an unsigned integer in octal, decimal, or * hexadecimal (with lower-case or upper-case letters).
\%sFormat a C string (const char *). * The alternate form \%\#s calls String::printable() on the * input string. Both \%\#s and the alternate form \%'s * ensure that no part of the string is mistaken for an error * annotation.
\%cFormat a character. Prints a C-like * escape if the input character isn't printable ASCII.
\%pFormat a pointer as a hexadecimal * value.
\%e, \%E, \%f, \%F, * \%g, \%GFormat a double (user-level * only).
\%p{...}Call a user-provided conversion function. * For example, \%p{ip_ptr} reads an IPAddress * argument * from the argument list, and formats the pointed-to address using * IPAddress::unparse().
\%\%Format a literal \% character.
\%\<Format a left quote string. Usually * prints a single quote.
\%\>Format a right quote string. Usually * prints a single quote.
\%,Format an apostrophe string. Usually * prints a single quote.
*/ static String xformat(int default_flags, const char *fmt, ...); /** @overload */ static String vxformat(int default_flags, const char *fmt, va_list val); /** @overload */ static String xformat(const char *fmt, ...); /** @overload */ static String vxformat(const char *fmt, va_list val) { return vxformat(0, fmt, val); } /** @brief Format an error string. * @param fmt format string * @param val argument list * * @warning ErrorHandler users don't need to call this function directly; * it is called implicitly by the error()/xmessage() functions. * * This virtual function is called to format an error message. The * default implementation returns the result of vxformat(@a fmt, @a val). */ virtual String vformat(const char *fmt, va_list val); /** @brief Format an error string. * @param fmt format string * * @warning ErrorHandler users don't usually need to call this function * directly. * * This is a convenience function that calls vformat(const char *fmt, * va_list val) for a va_list taken from the ellipsis arguments. */ String format(const char *fmt, ...); /** @brief Decorate an error message. * @param str error message, possibly with annotations * @return decorated error message * * @warning ErrorHandler users don't need to call this function directly; * it is called implicitly by the error()/xmessage() functions. * * This virtual function is called to decorate an error message before it * is emitted. The input @a str is an error message string, possibly * annotated. The default implementation returns @a str unchanged. Other * ErrorHandlers might add context lines (ContextErrorHandler), prefixes * (PrefixErrorHandler), or a default landmark (LandmarkErrorHandler). */ virtual String decorate(const String &str); /** @brief Output an error message line. * @param str error message line, possibly with annotations * @param user_data callback data, 0 for first line in a message * @param more true iff this is the last line in the current message * @return @a user_data to be passed to emit() for the next line * * @warning ErrorHandler users don't need to call this function directly; * it is called implicitly by the error()/xmessage() functions. * * After calling decorate(), ErrorHandler splits the message into * individual lines and calls emit() once per line. ErrorHandler * subclasses should output the error lines as appropriate; for example, * FileErrorHandler outputs the error message to a file. * * @a str does not contain a newline, but may contain annotations, * including a landmark annotation. Most ErrorHandlers use parse_anno() * to extract the landmark annotation, clean it with clean_landmark(), and * print it ahead of the error message proper. * * ErrorHandler can handle multi-line error messages. However, the emit() * function takes a line at a time; this is more useful in practice for * most error message printers. The @a user_data and @a more arguments * can help an ErrorHandler combine the lines of a multi-line error * message. @a user_data is null for the first line; for second and * subsequent lines, ErrorHandler passes the result of the last line's * emit() call. @a more is true iff this is the last line in the current * message. * * The default emit() implementation does nothing. */ virtual void *emit(const String &str, void *user_data, bool more); /** @brief Account for an error message at level @a level. * @param level minimum error level in the message * * @warning ErrorHandler users don't need to call this function directly; * it is called implicitly by the error()/xmessage() functions. * * After calling emit() for the lines of an error message, ErrorHandler * calls account(), passing the minimum (worst) error level of any message * line (or 1000 if no line had a level). The default implementation * updates the nerrors() counter, and exits the program if @a level is * small enough. */ virtual void account(int level); /** @brief Clear accumulated error state. * * The default implementation sets the nerrors() counter to zero. */ virtual void clear() { _nerrors = 0; } /** @brief Create an error annotation. * @param name annotation name * @param value annotation value * @return annotation string * * Returns an error annotation that associates annotation @a name with @a * value. * * If @a name equals "<>", then returns a level annotation of the form * "<@a value>". @a value must be valid number; if it isn't, the function * returns the empty string. * * Otherwise, @a name must be a nonempty series of letters and digits. * make_anno() returns a string of the form "{@a name:@a value}", where * special characters in @a value are quoted with backslashes. */ static String make_anno(const char *name, const String &value); /** @brief Apply annotations from @a anno to every line in @a str. * @param str string * @param anno annotation string * * The annotations from @a anno are applied to every line in @a str. New * annotations do not override existing annotations with the same names. * If the @a anno string ends with non-annotation characters, this * substring is prefixed to every line in @a str. * * For example: * @code * combine_anno("Line 1\n{l:old}{x:x}Line 2\n", "<0>{l:new} ") * // returns "<0>{l:new} Line 1\n<0>{l:old}{x:x} Line 2\n" * @endcode */ static String combine_anno(const String &str, const String &anno); /** @brief Parse error annotations from a string. * @param str the string * @param begin pointer within @a str to start of annotation area * @param end pointer to end of error region, usually @a str.end() * @return pointer to first character after annotation area * @pre @a str.begin() <= {@a begin, @a end} <= @a str.end() * @post @a begin <= returned value <= @a end * * Use this function to skip an error line's annotation area, possibly * extracting named annotations. * * The variable arguments portion consists of a series of pairs of C * strings and value pointers, terminated by a null character pointer. * Each C string is an annotation name. The corresponding annotation * value, if found, is stored as a String object in the value pointer. * You can also store the int value of an annotation by prefixing * an annotation name with the '#' character. * * For example: * @code * String line = "{l:file:30}<4.5>error message\n"; * String landmark_str, level_str; * const char *s = ErrorHandler::parse_anno(line, line.begin(), line.end(), * "l", &landmark_str, "<>", &level_str, (const char *) 0); * // Results: s points to "error message\n", * // landmark_str == "file:30", level_str == "4.5" * * int level; * s = ErrorHandler::parse_anno(line, line.begin(), line.end(), * "#<>", &level, (const char *) 0); * // Results: s points to "error message\n", level_str == 4 * @endcode */ static const char *parse_anno(const String &str, const char *begin, const char *end, ...) ERRH_SENTINEL; /** @brief Skip a string's error annotations. * @param begin pointer to start of string * @param end pointer one past end of string * @return pointer to first character after annotation area * @post @a begin <= returned value <= @a end * * Use this function to skip an error line's annotation area. The error * line is defined as a pair of iterators. */ static const char *skip_anno(const char *begin, const char *end) { String name, value; const char *x = begin; do { x = skip_anno(String(), x, end, &name, &value, false); } while (name); return x; } /** @brief Return a landmark annotation equal to @a x. * @param x landmark * * If @a x is empty, returns the empty string. Otherwise, if @a x looks * like a formatted annotation (it starts with an open brace), returns @a * x unchanged. Otherwise, returns make_anno("l", @a x). */ static String make_landmark_anno(const String &x) { if (x && x[0] == '{') return x; else if (x) return make_anno("l", x); else return String(); } /** @brief Clean the @a landmark. * @param landmark landmark text * @param colon if true, append ": " to a nonempty landmark * * Removes trailing space and an optional trailing colon from @a landmark * and returns the result. If @a colon is true, and the cleaned landmark * isn't the empty string, then appends ": " to the result. */ static String clean_landmark(const String &landmark, bool colon = false); // error conversions struct Conversion; typedef String (*ConversionFunction)(int flags, VA_LIST_REF_T); enum ConversionFlags { cf_zero_pad = 1, ///< Set for conversions using the '0' flag. cf_plus_positive = 2, ///< Set for conversions using the '+' flag. cf_space_positive = 4, ///< Set for conversions using the ' ' flag. cf_left_just = 8, ///< Set for conversions using the '-' flag. cf_alternate_form = 16, ///< Set for conversions using the '#' flag. cf_singlequote = 32, ///< Set for conversions using the '\'' flag. cf_uppercase = 64, ///< Set for 'X' conversions (not 'x'). cf_signed = 128, ///< Set for conversions of signed numbers. cf_negative = 256, ///< Set for conversions of negative numbers. cf_utf8 = 1024 ///< Set to use UTF-8 characters on output. }; static Conversion *add_conversion(const String &name, ConversionFunction func); static int remove_conversion(Conversion *conversion); private: int _nerrors; static ErrorHandler *the_default_handler; static ErrorHandler *the_silent_handler; static const char *skip_anno(const String &str, const char *begin, const char *end, String *name_result, String *value_result, bool raw); }; /** @class SilentErrorHandler * @brief An ErrorHandler that does not report messages. * * Use SilentErrorHandler when an ErrorHandler object is required, but error * messages should not be printed. */ class SilentErrorHandler : public ErrorHandler { public: SilentErrorHandler() { } }; /** @class ErrorVeneer * @brief Base class for ErrorHandlers that forward messages. * * ErrorHandlers can stack. Stacking ErrorHandlers simplify modify a message * and then pass the result to a base ErrorHandler, which does the actual * printing. The ErrorVeneer base class simplifies the implementation of * stacking ErrorHandlers. It provides versions of ErrorHandler's format(), * decorate(), emit(), and account() methods that forward to the underlying * handler. Note that the clear() method is not automatically * forwarded. */ class ErrorVeneer : public ErrorHandler { public: /** @brief Construct an ErrorVeneer. * @param errh base ErrorHandler * * If @a errh is 0, then the ErrorVeneer acts like a * SilentErrorHandler. */ ErrorVeneer(ErrorHandler *errh) : _errh(errh) { } String vformat(const char *fmt, va_list val); String decorate(const String &str); void *emit(const String &str, void *user_data, bool more); void account(int level); private: ErrorHandler *_errh; }; #ifndef __KERNEL__ /** @class FileErrorHandler * @brief An ErrorHandler that prints error messages to a given file. * * FileErrorHandler is the typical base ErrorHandler used at user level. It * prints messages to a file passed in to the constructor, and calls exit() or * abort() based on the error level. */ class FileErrorHandler : public ErrorHandler { public: /** @brief Construct a FileErrorHandler. * @param f file to print errors * @param prefix string to prefix every error line */ FileErrorHandler(FILE *f, const String &prefix = String()); void set_default_flags(int default_flags) { _default_flags = default_flags; } String vformat(const char *fmt, va_list val); void *emit(const String &str, void *user_data, bool more); private: FILE *_f; String _context; int _default_flags; }; #endif /** @class LocalErrorHandler * @brief A convenience stackable ErrorHandler. * * It's often convenient to pass a null ErrorHandler pointer when errors * should not be printed. The LocalErrorHandler class simplifies dealing with * ErrorHandler pointers that may or may not be null. LocalErrorHandler is a * transparent layer on the base handler; but if the base handler is null, it * acts like a SilentErrorHandler. For example: * @code * void f(ErrorHandler *errh) { // errh might or might not be null * LocalErrorHandler lerrh(errh); * ... lerrh.message("message") ... * } * @endcode */ class LocalErrorHandler : public ErrorVeneer { public: /** @brief Construct a LocalErrorHandler. */ LocalErrorHandler(ErrorHandler *errh) : ErrorVeneer(errh) { } }; /** @class ContextErrorHandler * @brief A stackable ErrorHandler that prints context lines. * * The stackable ContextErrorHandler adds context to the first error * message printed, and optionally indent error messages so that they appear * grouped underneath the context. * @code * FileErrorHandler errh1(stderr); * ContextErrorHandler errh2(&errh1, "While counting to 2:"); * errh2.error("An error occurred."); * errh2.error("Another error occurred."); * // prints "While counting to 2:\n" * // " An error occurred.\n" * // " Another error occurred.\n" * @endcode * * To prevent ContextErrorHandler from indenting or printing context for a * message, add a "{context:no}" annotation to the message's first line. To * turn off the indent but keep the context, add a "{context:noindent}" * annotation. * @code * FileErrorHandler errh1(stderr); * ContextErrorHandler errh2(&errh1, "While counting to 2:"); * errh2.error("{context:no}An error occurred."); * errh2.error("Another error occurred."); * // prints "An error occurred.\n" * // "While counting to 2:\n" * // " Another error occurred.\n" * * FileErrorHandler errh1(stderr); * PrefixErrorHandler noctx_errh(stderr, "{context:no}"); * ContextErrorHandler errh2(&errh1, "While counting to 2:"); * errh2.error("An error occurred."); * errh2.error("Another error occurred."); * // prints "An error occurred.\n" * // "Another error occurred.\n" * @endcode * * ContextErrorHandler adds the "{context:context}" annotation to context * lines. */ class ContextErrorHandler : public ErrorVeneer { public: /** @brief Construct a ContextErrorHandler. * @param errh base ErrorHandler * @param fmt format for context lines * * The context message is formed by @a errh->format() using @a fmt and * any additional arguments. */ ContextErrorHandler(ErrorHandler *errh, const char *fmt, ...); /** @brief Return true iff the context has already been printed. */ bool context_printed() const { return _context_printed; } /** @brief Set whether the context has been printed. */ void set_context_printed(bool x) { _context_printed = x; } /** @brief Set the context string to @a str. */ void set_context(const String &str) { _context = str; } /** @brief Set the indent string to @a str. * * The indent string is prepended to all non-context messages. It can * contain landmarks as well as non-landmark text. The default indent * string is " " (two spaces). */ void set_indent(const String &str) { _indent = str; } /** @brief Set the context landmark to @a str. * * The context landmark is used to decorate the context, and also applied * to any error messages that lack landmarks of their own. The default * context landmark is empty. * * @note The input @a str is passed to * ErrorHandler::make_landmark_anno(). */ void set_context_landmark(const String &str) { _context_landmark = make_landmark_anno(str); } String decorate(const String &str); private: String _context; String _indent; String _context_landmark; bool _context_printed; }; /** @class PrefixErrorHandler * @brief A stackable ErrorHandler that adds a prefix to error messages. * * The stackable ContextErrorHandler adds a prefix to every error line * printed. For example: * @code * FileErrorHandler errh1(stderr); * PrefixErrorHandler errh2(&errh1, "Blah--"); * errh2.error("An error occurred."); * errh2.error("Another error occurred."); * // prints "Blah--An error occurred.\n" * // "Blah--Another error occurred.\n" * @endcode */ class PrefixErrorHandler : public ErrorVeneer { public: /** @brief Construct a PrefixErrorHandler. * @param errh base ErrorHandler * @param prefix string to prefix to error lines */ PrefixErrorHandler(ErrorHandler *errh, const String &prefix); String decorate(const String &str); private: String _prefix; }; /** @class LandmarkErrorHandler * @brief A stackable ErrorHandler that adds a default landmark to error * messages. * * The stackable ContextErrorHandler adds a default landmark to every error * line printed. Error lines' own landmarks are preserved when they exist. * For example: * @code * FileErrorHandler errh1(stderr); * LandmarkErrorHandler errh2(&errh1, "file:1"); * errh2.error("An error occurred."); * errh2.lerror("file:2", "Another error occurred."); * // prints "file:1: An error occurred.\n" * // "file:2: Another error occurred.\n" * @endcode */ class LandmarkErrorHandler : public ErrorVeneer { public: /** @brief Construct a LandmarkErrorHandler. * @param errh base ErrorHandler * @param landmark default landmark */ LandmarkErrorHandler(ErrorHandler *errh, const String &landmark); /** @brief Set the default landmark applied to error messages. */ void set_landmark(const String &landmark) { _landmark = make_landmark_anno(landmark); } String decorate(const String &str); private: String _landmark; }; #ifndef __KERNEL__ /** @class BailErrorHandler * @brief A stackable ErrorHandler that exits when errors occur. * * The stackable BailErrorHandler, available only at user level, causes the * process to exit if an error worse than a configurable level occurs. */ class BailErrorHandler : public ErrorVeneer { public: /** @brief Construct a BailErrorHandler. * @param errh base ErrorHandler * @param level error level that causes premature exit * * An error message with level less than or equal to @a el_error will * cause the process to exit with status 1. */ BailErrorHandler(ErrorHandler *errh, int level = el_error); void account(int level); private: int _level; }; #endif #undef ERRH_SENTINEL #endif lcdf-typetools-2.108/include/lcdf/hashcode.hh0000664000175000017500000000073412732752520016062 00000000000000#ifndef LCDF_HASHCODE_HH #define LCDF_HASHCODE_HH #include typedef size_t hashcode_t; ///< Typical type for a hashcode() value. inline hashcode_t hashcode(int x) { return static_cast(x); } inline hashcode_t hashcode(unsigned x) { return static_cast(x); } inline hashcode_t hashcode(long x) { return static_cast(x); } inline hashcode_t hashcode(unsigned long x) { return static_cast(x); } #endif lcdf-typetools-2.108/include/lcdf/globmatch.hh0000664000175000017500000000030112732752520016232 00000000000000// -*- related-file-name: "../../liblcdf/globmatch.cc" -*- #ifndef LCDF_GLOBMATCH_HH #define LCDF_GLOBMATCH_HH class String; bool glob_match(const String& str, const String& pattern); #endif lcdf-typetools-2.108/include/lcdf/landmark.hh0000664000175000017500000000156112732752520016074 00000000000000// -*- related-file-name: "../../liblcdf/landmark.cc" -*- #ifndef LCDF_LANDMARK_HH #define LCDF_LANDMARK_HH #include class Landmark { public: Landmark() : _file(), _line(~0U) { } explicit Landmark(const String &f) : _file(f), _line(~0U) { } Landmark(const String &f, unsigned l) : _file(f), _line(l) { } operator bool() const { return _file; } bool operator!() const { return !_file; } bool has_line() const { return _line != ~0U; } const String &file() const { return _file; } unsigned line() const { return _line; } Landmark next_line() const; Landmark whole_file() const { return Landmark(_file); } operator String() const; private: String _file; unsigned _line; }; Landmark operator+(const Landmark &, int); inline Landmark Landmark::next_line() const { return *this + 1; } #endif lcdf-typetools-2.108/include/lcdf/hashmap.cc0000664000175000017500000001025012732752520015705 00000000000000#ifndef LCDF_HASHMAP_CC #define LCDF_HASHMAP_CC /* * hashmap.{cc,hh} -- simple open-coded hash table class * Eddie Kohler * * Copyright (c) 1999-2000 Massachusetts Institute of Technology * Copyright (c) 2001-2003 International Computer Science Institute * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file. These conditions include: you must * preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */ /* #include */ template HashMap::HashMap() : _capacity(0), _grow_limit(0), _n(0), _e(0), _default_value() { increase(-1); } template HashMap::HashMap(const V &def) : _capacity(0), _grow_limit(0), _n(0), _e(0), _default_value(def) { increase(-1); } template HashMap::HashMap(const HashMap &m) : _capacity(m._capacity), _grow_limit(m._grow_limit), _n(m._n), _e(new Pair[m._capacity]), _default_value(m._default_value) { for (int i = 0; i < _capacity; i++) _e[i] = m._e[i]; } template HashMap & HashMap::operator=(const HashMap &o) { // This works with self-assignment. _capacity = o._capacity; _grow_limit = o._grow_limit; _n = o._n; _default_value = o._default_value; Pair *new_e = new Pair[_capacity]; for (int i = 0; i < _capacity; i++) new_e[i] = o._e[i]; delete[] _e; _e = new_e; return *this; } template void HashMap::increase(int min_size) { int ncap = (_capacity < 8 ? 8 : _capacity * 2); while (ncap < min_size && ncap > 0) ncap *= 2; if (ncap <= 0) // want too many elements return; Pair *ne = new Pair[ncap]; if (!ne) // out of memory return; Pair *oe = _e; int ocap = _capacity; _e = ne; _capacity = ncap; _grow_limit = ((3 * _capacity) >> 2) - 1; Pair *otrav = oe; for (int i = 0; i < ocap; i++, otrav++) if (otrav->key) { int j = bucket(otrav->key); _e[j] = *otrav; } delete[] oe; } template inline void HashMap::check_capacity() { if (_n >= _grow_limit) increase(-1); } template bool HashMap::insert(const K &key, const V &val) { check_capacity(); int i = bucket(key); bool is_new = !(bool)_e[i].key; _e[i].key = key; _e[i].value = val; _n += is_new; return is_new; } template V & HashMap::find_force(const K &key, const V &value) { check_capacity(); int i = bucket(key); if (!(bool)_e[i].key) { _e[i].key = key; _e[i].value = value; _n++; } return _e[i].value; } template void HashMap::clear() { delete[] _e; _e = 0; _capacity = _grow_limit = _n = 0; increase(-1); } template void HashMap::swap(HashMap &o) { int capacity = _capacity; int grow_limit = _grow_limit; int n = _n; Pair *e = _e; V default_value = _default_value; _capacity = o._capacity; _grow_limit = o._grow_limit; _n = o._n; _e = o._e; _default_value = o._default_value; o._capacity = capacity; o._grow_limit = grow_limit; o._n = n; o._e = e; o._default_value = default_value; } template _HashMap_const_iterator::_HashMap_const_iterator(const HashMap *hm, int pos) : _hm(hm), _pos(pos) { typename HashMap::Pair *e = _hm->_e; int capacity = _hm->_capacity; while (_pos < capacity && !(bool)e[_pos].key) _pos++; } template void _HashMap_const_iterator::operator++(int) { typename HashMap::Pair *e = _hm->_e; int capacity = _hm->_capacity; for (_pos++; _pos < capacity && !(bool)e[_pos].key; _pos++) ; } #endif lcdf-typetools-2.108/include/lcdf/slurper.hh0000664000175000017500000000244112732752520015775 00000000000000// -*- related-file-name: "../../liblcdf/slurper.cc" -*- #ifndef LCDF_SLURPER_HH #define LCDF_SLURPER_HH #include #include #include class Slurper { public: Slurper(const Filename &, FILE * = 0); ~Slurper(); bool ok() const { return _f != 0; } Landmark landmark() const { return Landmark(_filename.name(), _lineno); } operator Landmark() const { return landmark(); } unsigned lineno() const { return _lineno; } const Filename &filename() const { return _filename; } char *peek_line(); char *next_line(); char *append_next_line(); void save_line() { _saved_line = true; } char *cur_line() const { return (char *)_line; } unsigned cur_line_length() const { return _line_len; } void shorten_line(unsigned); private: FILE *_f; Filename _filename; unsigned _lineno; bool _own_f; unsigned char *_data; unsigned _cap; unsigned _pos; unsigned _len; unsigned char *_line; unsigned _line_len; bool _saved_line; bool _at_eof; void grow_buffer(); inline int more_data(); char *get_line_at(unsigned); }; inline void Slurper::shorten_line(unsigned pos) { if (pos < _line_len) { _line_len = pos; _line[_line_len] = 0; } } #endif lcdf-typetools-2.108/include/lcdf/transform.hh0000664000175000017500000000672712732752520016327 00000000000000// -*- related-file-name: "../../liblcdf/transform.cc" -*- #ifndef LCDF_TRANSFORM_HH #define LCDF_TRANSFORM_HH #include #include #include class Transform { public: Transform(); Transform(const double[6]); Transform(double scalex, double sheary, double shearx, double scaley, double shiftx, double shifty); // Transform(const Transform &) generated by compiler // ~Transform() generated by compiler double operator[](int i) const { assert(i>=0&&i<6); return _m[i]; } Point translation() const { return Point(_m[4], _m[5]); } bool null() const { return _null; } void check_null(double tolerance); void scale(double, double); void scale(const Point &p) { scale(p.x, p.y); } void scale(double d) { scale(d, d); } void rotate(double); void translate(double, double); void translate(const Point &p) { translate(p.x, p.y); } void raw_translate(double, double); void raw_translate(const Point& p) { raw_translate(p.x, p.y); } void shear(double); Transform& operator*=(const Transform& x); inline Transform scaled(double, double) const; Transform scaled(const Point &p) const { return scaled(p.x, p.y); } Transform scaled(double d) const { return scaled(d, d); } inline Transform rotated(double) const; inline Transform translated(double, double) const; inline Transform translated(const Point &p) const; inline Transform sheared(double) const; // Transform operator+(Transform, const Point &); // Transform &operator+=(Transform &, const Point &); // Transform operator*(Transform, double); // Transform &operator*=(Transform &, double); // Transform operator*(Transform, const Transform &); // Transform &operator*=(Transform &, const Transform &); friend Point operator*(const Point &, const Transform &); friend Point &operator*=(Point &, const Transform &); friend Bezier operator*(const Bezier &, const Transform &); friend Bezier &operator*=(Bezier &, const Transform &); String unparse() const; private: // stored in PostScript order (along columns) double _m[6]; bool _null; void real_apply_to(Point &) const; Point real_apply(const Point &) const; }; inline Transform Transform::scaled(double x, double y) const { Transform t(*this); t.scale(x, y); return t; } inline Transform Transform::rotated(double r) const { Transform t(*this); t.rotate(r); return t; } inline Transform Transform::translated(double x, double y) const { Transform t(*this); t.translate(x, y); return t; } inline Transform Transform::translated(const Point &p) const { return translated(p.x, p.y); } inline Transform Transform::sheared(double s) const { Transform t(*this); t.shear(s); return t; } inline Transform & operator+=(Transform &t, const Point &p) { t.translate(p); return t; } inline Transform operator+(Transform t, const Point &p) { return t += p; } inline Transform & operator*=(Transform &t, double scale) { t.scale(scale); return t; } inline Transform operator*(Transform t, double scale) { return t *= scale; } inline Transform operator*(Transform a, const Transform& b) { return a *= b; } inline Point & operator*=(Point &p, const Transform &t) { if (!t.null()) t.real_apply_to(p); return p; } inline Point operator*(const Point &p, const Transform &t) { return (t.null() ? p : t.real_apply(p)); } #endif lcdf-typetools-2.108/include/lcdf/permstr.hh0000664000175000017500000001051312732752520015774 00000000000000// -*- related-file-name: "../../liblcdf/permstr.cc" -*- #ifndef LCDF_PERMSTR_HH #define LCDF_PERMSTR_HH #include #include #include #include #include #include class PermString; inline bool operator==(PermString a, PermString b); inline bool operator!=(PermString a, PermString b); class PermString { struct Doodad; public: typedef Doodad *Capsule; // Declare a PermString::Initializer in any file in which you declare // static global PermStrings. struct Initializer { Initializer(); }; PermString() : _rep(zero_char_doodad.data) { } explicit PermString(char c) : _rep(one_char_doodad[(unsigned char) c].data) { } inline PermString(const char *s); inline PermString(const char *s, int len); inline PermString(const char *begin, const char *end); typedef int (PermString::*unspecified_bool_type)() const; inline operator unspecified_bool_type() const; inline bool operator!() const; inline int length() const; char operator[](int i) const; inline const char* data() const { return _rep; } inline const char *c_str() const { return _rep; } inline char operator*() const { return *_rep; } inline const char *begin() const; inline const char *end() const; inline bool equals(const char *s, int len) const; friend inline bool operator==(PermString a, PermString b); friend inline bool operator!=(PermString a, PermString b); inline Capsule capsule() const; inline static PermString decapsule(Capsule c); friend PermString permprintf(const char*, ...); friend PermString vpermprintf(const char*, va_list); friend PermString permcat(PermString, PermString); friend PermString permcat(PermString, PermString, PermString); private: struct Doodad { Doodad *next; int length; char data[2]; }; const char *_rep; PermString(Doodad* d) : _rep(d->data) { } void initialize(const char*, int); Doodad* doodad() const { return (Doodad*)(_rep - offsetof(Doodad, data)); } friend struct PermString::Initializer; static void static_initialize(); enum { NHASH = 1024 }; // must be power of 2 static Doodad zero_char_doodad, one_char_doodad[256], *buckets[NHASH]; }; inline PermString::PermString(const char* s) { initialize(s, -1); } inline PermString::PermString(const char* s, int len) { initialize(s, len); } inline PermString::PermString(const char* begin, const char* end) { assert(end); initialize(begin, end > begin ? end - begin : 0); } inline PermString::operator unspecified_bool_type() const { return _rep != zero_char_doodad.data ? &PermString::length : 0; } inline bool PermString::operator!() const { return _rep == zero_char_doodad.data; } inline int PermString::length() const { return doodad()->length; } inline const char *PermString::begin() const { return _rep; } inline const char *PermString::end() const { return _rep + doodad()->length; } inline char PermString::operator[](int i) const { assert((unsigned) i < (unsigned) length()); return c_str()[i]; } inline bool operator==(PermString a, PermString b) { return a._rep == b._rep; } inline bool operator==(PermString a, const char *b) { return (!a || !b ? !a && !b : strcmp(a.c_str(), b) == 0); } inline bool operator==(const char *a, PermString b) { return b == a; } inline bool operator!=(PermString a, PermString b) { return a._rep != b._rep; } inline bool operator!=(PermString a, const char *b) { return !(a == b); } inline bool operator!=(const char *a, PermString b) { return !(b == a); } inline bool operator<(PermString a, PermString b) { // NOT lexicographic ordering! return a.begin() < b.begin(); } inline bool PermString::equals(const char *s, int len) const { if (len > 0) return len == length() && memcmp(s, _rep, len) == 0; else return strcmp(s, _rep) == 0; } inline PermString::Capsule PermString::capsule() const { return doodad(); } inline PermString PermString::decapsule(Capsule c) { return PermString(c); } inline hashcode_t hashcode(PermString s) { return (uintptr_t) s.c_str(); } PermString permprintf(const char *format, ...); PermString vpermprintf(const char *format, va_list val); PermString permcat(PermString a, PermString b); #endif lcdf-typetools-2.108/include/lcdf/string.hh0000664000175000017500000006553012732752520015617 00000000000000// -*- related-file-name: "../../liblcdf/string.cc" -*- #ifndef LCDF_STRING_HH #define LCDF_STRING_HH #include #ifdef HAVE_PERMSTRING # include #endif #include class StringAccum; class String { public: /** @brief Construct an empty String (with length 0). */ inline String() { assign_memo(&null_data, 0, 0); } /** @brief Construct a copy of the String @a x. */ inline String(const String &x) { assign(x); } /** @brief Construct a String containing the C string @a cstr. * @param cstr a null-terminated C string * @return A String containing the characters of @a cstr, up to but not * including the terminating null character. * * If @a cstr equals String::out_of_memory_data(), returns an * out-of-memory string. */ inline String(const char *cstr) { assign(cstr, -1, false); } /** @brief Construct a String containing the first @a len characters of * string @a s. * @param s a string * @param len number of characters to take from @a s. If @a len @< 0, * then takes @c strlen(@a s) characters. * @return A String containing @a len characters of @a s. * * If @a s equals String::out_of_memory_data(), returns an out-of-memory * string. */ inline String(const char *s, int len) { assign(s, len, false); } /** @overload */ inline String(const unsigned char *s, int len) { assign(reinterpret_cast(s), len, false); } /** @brief Construct a String containing the characters from @a begin * to @a end. * @param begin first character in string (begin iterator) * @param end pointer one past last character in string (end iterator) * @return A String containing the characters from @a begin to @a end. * * Returns a null string if @a begin @>= @a end. If @a begin equals * String::out_of_memory_data(), returns an out-of-memory string. */ inline String(const char *begin, const char *end) { assign(begin, (end > begin ? end - begin : 0), false); } /** @overload */ inline String(const unsigned char *begin, const unsigned char *end) { assign(reinterpret_cast(begin), (end > begin ? end - begin : 0), false); } /** @brief Construct a String equal to "true" or "false" depending on the * value of @a x. */ explicit inline String(bool x) { assign_memo(bool_data + (x ? 0 : 5), x ? 4 : 5, 0); } /** @brief Construct a String containing the single character @a c. */ explicit inline String(char c) { assign(&c, 1, false); } /** @overload */ explicit inline String(unsigned char c) { assign(reinterpret_cast(&c), 1, false); } /** @brief Construct a base-10 string representation of @a x. */ explicit String(int x); /** @overload */ explicit String(unsigned x); /** @overload */ explicit String(long x); /** @overload */ explicit String(unsigned long x); /** @overload */ explicit String(double x); #if HAVE_PERMSTRING inline String(PermString x) { assign(x); } #endif /** @brief Destroy a String, freeing memory if necessary. */ inline ~String() { deref(); } /** @brief Return a const reference to an empty String. * * May be quicker than String::String(). */ static inline const String &make_empty() { return reinterpret_cast(null_string_rep); } /** @brief Return a String containing @a len unknown characters. */ static String make_uninitialized(int len) { String s; s.append_uninitialized(len); return s; } /** @brief Return a String that directly references the first @a len * characters of @a s. * * This function is suitable for static constant strings whose data is * known to stay around forever, such as C string constants. If @a len @< * 0, treats @a s as a null-terminated C string. * * @warning The String implementation may access @a s[@a len], which * should remain constant even though it's not part of the String. */ static String make_stable(const char *s, int len = -1); /** @brief Return a String that directly references the character data in * [@a begin, @a end). * @param begin pointer to the first character in the character data * @param end pointer one beyond the last character in the character data * (but see the warning) * * This function is suitable for static constant strings whose data is * known to stay around forever, such as C string constants. Returns an * empty string if @a begin @>= @a end. * * @warning The String implementation may access *@a end, which should * remain constant even though it's not part of the String. */ static inline String make_stable(const char *begin, const char *end) { if (begin < end) return String::make_stable(begin, end - begin); else return String(); } static String make_fill(int c, int n); // n copies of c /** @brief Return the string's length. */ inline int length() const { return _r.length; } /** @brief Return a pointer to the string's data. * * Only the first length() characters are valid, and the string data * might not be null-terminated. */ inline const char *data() const { return _r.data; } /** @brief Return a pointer to the string's data as unsigned chars. * * Only the first length() characters are valid, and the string data * might not be null-terminated. @sa data() */ inline const unsigned char *udata() const { return reinterpret_cast(_r.data); } typedef const char *const_iterator; typedef const_iterator iterator; /** @brief Return an iterator for the first character in the string. * * String iterators are simply pointers into string data, so they are * quite efficient. @sa String::data */ inline const_iterator begin() const { return _r.data; } /** @brief Return an iterator for the end of the string. * * The return value points one character beyond the last character in the * string. */ inline const_iterator end() const { return _r.data + _r.length; } inline const unsigned char* ubegin() const { return reinterpret_cast(_r.data); } inline const unsigned char* uend() const { return reinterpret_cast(_r.data + _r.length); } typedef int (String::*unspecified_bool_type)() const; /** @brief Return true iff the string is nonempty. */ inline operator unspecified_bool_type() const { return _r.length != 0 ? &String::length : 0; } /** @brief Return true iff the string is empty. */ inline bool empty() const { return _r.length == 0; } /** @brief Return true iff the string is empty. */ inline bool operator!() const { return empty(); } /** @brief Return the @a i th character in the string. * * Does not check bounds. @sa String::at */ inline char operator[](int i) const { return _r.data[i]; } /** @brief Return the @a i th character in the string. * * Checks bounds: an assertion will fail if @a i is less than 0 or not * less than length(). @sa String::operator[] */ inline char at(int i) const { assert((unsigned) i < (unsigned) _r.length); return _r.data[i]; } /** @brief Return the first character in the string. * * Does not check bounds. Same as (*this)[0]. */ inline char front() const { return _r.data[0]; } /** @brief Return the last character in the string. * * Does not check bounds. Same as (*this)[length() - 1]. */ inline char back() const { return _r.data[_r.length - 1]; } /** @brief Null-terminate the string. * * The terminating null character isn't considered part of the string, so * this->length() doesn't change. Returns a corresponding C string * pointer. The returned pointer is semi-temporary; it will persist until * the string is destroyed or appended to. */ inline const char *c_str() const { // We may already have a '\0' in the right place. If _memo has no // capacity, then this is one of the special strings (null or // stable). We are guaranteed, in these strings, that _data[_length] // exists. Otherwise must check that _data[_length] exists. const char *end_data = _r.data + _r.length; if ((_r.memo && end_data >= _r.memo->real_data + _r.memo->dirty) || *end_data != '\0') { if (char *x = const_cast(this)->append_uninitialized(1)) { *x = '\0'; --_r.length; } } return _r.data; } #if HAVE_PERMSTRING operator PermString() const { return PermString(_r.data, _r.length); } #endif /** @brief Return a 32-bit hash function of the characters in [begin, end). * * Uses Paul Hsieh's "SuperFastHash" algorithm, described at * http://www.azillionmonkeys.com/qed/hash.html * This hash function uses all characters in the string. * * @invariant If end1 - begin1 == end2 - begin2 and memcmp(begin1, begin2, * end1 - begin1) == 0, then hashcode(begin1, end1) == hashcode(begin2, * end2). */ static hashcode_t hashcode(const char *begin, const char *end); /** @overload */ static inline hashcode_t hashcode(const unsigned char *begin, const unsigned char *end) { return hashcode(reinterpret_cast(begin), reinterpret_cast(end)); } /** @brief Returns a 32-bit hash function of this string's characters. * * Equivalent to String::hashcode(begin(), end()). Uses Paul Hsieh's * "SuperFastHash." * * @invariant If s1 == s2, then s1.hashcode() == s2.hashcode(). */ inline hashcode_t hashcode() const { return length() ? hashcode(begin(), end()) : 0; } /** @brief Return true iff this string is equal to the data in @a s. * @param s string data to compare to * @param len length of @a s * * Same as String::compare(*this, String(s, len)) == 0. If @a len @< 0, * then treats @a s as a null-terminated C string. * * @sa String::compare(const String &a, const String &b) */ bool equals(const char *s, int len) const; // bool operator==(const String &, const String &); // bool operator==(const String &, const char *); // bool operator==(const char *, const String &); // bool operator!=(const String &, const String &); // bool operator!=(const String &, const char *); // bool operator!=(const char *, const String &); /** @brief Compare two strings. * @param a first string to compare * @param b second string to compare * * Returns 0 if @a a == @a b, negative if @a a @< @a b in lexicographic * order, and positive if @a a @> @a b in lexicographic order. The * lexicographic order treats all characters as unsigned. */ static inline int compare(const String &a, const String &b) { return a.compare(b); } /** @brief Compare this string with string @a x. * * Same as String::compare(*this, @a x). * @sa String::compare(const String &a, const String &b) */ inline int compare(const String &x) const { return compare(x._r.data, x._r.length); } /** @brief Compare this string with the data in @a s. * @param s string data to compare to * @param len length of @a s * * Same as String::compare(*this, String(s, len)). If @a len @< 0, then * treats @a s as a null-terminated C string. * * @sa String::compare(const String &a, const String &b) */ int compare(const char *s, int len) const; // bool operator<(const String &, const String &); // bool operator<=(const String &, const String &); // bool operator>(const String &, const String &); // bool operator>=(const String &, const String &); /** @brief Return a substring of the current string starting at @a begin * and ending before @a end. * @param begin pointer to the first substring character * @param end pointer one beyond the last substring character * * Returns an empty string if @a begin @>= @a end. Also returns an empty * string if @a begin or @a end is out of range (i.e., either less than * this->begin() or greater than this->end()), but this should be * considered a programming error; a future version may generate a warning * for this case. */ inline String substring(const char *begin, const char *end) const { if (begin < end && begin >= _r.data && end <= _r.data + _r.length) return String(begin, end - begin, _r.memo); else return String(); } /** @overload */ inline String substring(const unsigned char* first, const unsigned char* last) const { return substring(reinterpret_cast(first), reinterpret_cast(last)); } /** @brief Return a substring of this string, consisting of the @a len * characters starting at index @a pos. * @param pos substring's first position relative to the string * @param len length of substring * * If @a pos is negative, starts that far from the end of the string. If * @a len is negative, leaves that many characters off the end of the * string. If @a pos and @a len specify a substring that is partly * outside the string, only the part within the string is returned. If * the substring is beyond either end of the string, returns an empty * string (but this should be considered a programming error; a future * version may generate a warning for this case). * * @note String::substring() is intended to behave like Perl's substr(). */ String substring(int pos, int len) const; /** @brief Return the suffix of the current string starting at index @a pos. * * If @a pos is negative, starts that far from the end of the string. If * @a pos is so negative that the suffix starts outside the string, then * the entire string is returned. If the substring is beyond the end of * the string (@a pos > length()), returns an empty string (but this * should be considered a programming error; a future version may generate * a warning for this case). * * @note String::substring() is intended to behave like Perl's substr(). */ inline String substring(int pos) const { return substring((pos <= -_r.length ? 0 : pos), _r.length); } /** @brief Search for a character in a string. * @param c character to search for * @param start initial search position * * Return the index of the leftmost occurence of @a c, starting at index * @a start and working up to the end of the string. Returns -1 if @a c * is not found. */ int find_left(char c, int start = 0) const; /** @brief Search for a substring in a string. * @param x substring to search for * @param start initial search position * * Return the index of the leftmost occurence of the substring @a str, * starting at index @a start and working up to the end of the string. * Returns -1 if @a str is not found. */ int find_left(const String &x, int start = 0) const; /** @brief Search for a character in a string. * @param c character to search for * @param start initial search position * * Return the index of the rightmost occurence of the character @a c, * starting at index @a start and working back to the beginning of the * string. Returns -1 if @a c is not found. @a start may start beyond * the end of the string. */ int find_right(char c, int start = 0x7FFFFFFF) const; /** @brief Return true iff this string begins with prefix @a x. * * Same as String::starts_with(@a x.data(), @a x.length()). */ inline bool starts_with(const String &x) const { return starts_with(x._r.data, x._r.length); } /** @brief Return true iff this string begins with the data in @a s. * @param s string data to compare to * @param len length of @a s * * If @a len @< 0, then treats @a s as a null-terminated C string. * * @sa String::compare(const String &a, const String &b) */ bool starts_with(const char *s, int len) const; String lower() const; String upper() const; String printable(int type = 0) const; /** @brief Assign this string to @a x. */ inline String &operator=(const String &x) { if (&x != this) { deref(); assign(x); } return *this; } /** @brief Assign this string to the C string @a cstr. */ inline String &operator=(const char *cstr) { assign(cstr, -1, true); return *this; } #ifdef HAVE_PERMSTRING inline String &operator=(PermString p) { deref(); assign(p); return *this; } #endif /** @brief Append the null-terminated C string @a cstr to this string. * @param cstr data to append */ inline void append(const char *cstr) { append(cstr, -1, 0); } /** @brief Append the first @a len characters of @a s to this string. * @param s data to append * @param len length of data * @pre @a len @>= 0 */ inline void append(const char *s, int len) { append(s, len, 0); } /** @brief Appends the data from @a begin to @a end to the end of this * string. * * Does nothing if @a begin @>= @a end. */ inline void append(const char *begin, const char *end) { if (begin < end) append(begin, end - begin); } /** @brief Append @a len copies of character @a c to this string. */ void append_fill(int c, int len); /** @brief Append @a len unknown characters to this string. * @return Modifiable pointer to the appended characters. * * The caller may safely modify the returned memory. Null is returned if * the string becomes out-of-memory. */ char *append_uninitialized(int len); /** @brief Append a copy of @a x to the end of this string. * * Returns the result. */ inline String &operator+=(const String &x) { append(x._r.data, x._r.length, x._r.memo); return *this; } /** @brief Append a copy of the C string @a cstr to the end of this string. * * Returns the result. */ inline String &operator+=(const char *cstr) { append(cstr); return *this; } /** @brief Append the character @a c to the end of this string. * * Returns the result. */ inline String &operator+=(char c) { append(&c, 1); return *this; } #if HAVE_PERMSTRING inline String &operator+=(PermString p) { append(p.c_str(), p.length()); return *this; } #endif // String operator+(String, const String &); // String operator+(String, const char *); // String operator+(const char *, const String &); // String operator+(String, PermString); // String operator+(PermString, String); // String operator+(PermString, const char *); // String operator+(const char *, PermString); // String operator+(PermString, PermString); // String operator+(String, char); /** @brief Return true iff the String's data is shared or immutable. */ inline bool data_shared() const { return !_r.memo || _r.memo->refcount != 1; } /** @brief Return a compact version of this String. * * The compact version shares no more than 256 bytes of data with any * other non-stable String. */ inline String compact() const { if (!_r.memo || _r.memo->refcount == 1 || (uint32_t) _r.length + 256 >= _r.memo->capacity) return *this; else return String(_r.data, _r.data + _r.length); } /** @brief Ensure the string's data is unshared and return a mutable * pointer to it. */ char *mutable_data(); /** @brief Null-terminate the string and return a mutable pointer to its * data. * @sa String::c_str */ char *mutable_c_str(); unsigned char *mutable_udata() { return reinterpret_cast(mutable_data()); } void align(int); /** @brief Return true iff this is an out-of-memory string. */ inline bool out_of_memory() const { return _r.data == &oom_data; } /** @brief Return a const reference to an out-of-memory String. */ static inline const String &make_out_of_memory() { return reinterpret_cast(oom_string_rep); } /** @brief Return the data pointer used for out-of-memory strings. * * The returned value may be dereferenced; it points to a null * character. */ static inline const char *out_of_memory_data() { return &oom_data; } private: /** @cond never */ struct memo_t { volatile uint32_t refcount; uint32_t capacity; volatile uint32_t dirty; #if HAVE_STRING_PROFILING > 1 memo_t **pprev; memo_t *next; #endif char real_data[8]; // but it might be more or less }; enum { MEMO_SPACE = sizeof(memo_t) - 8 }; struct rep_t { const char *data; int length; memo_t *memo; }; /** @endcond never */ mutable rep_t _r; // mutable for c_str() #if HAVE_STRING_PROFILING static uint64_t live_memo_count; static uint64_t memo_sizes[55]; static uint64_t live_memo_sizes[55]; static uint64_t live_memo_bytes[55]; # if HAVE_STRING_PROFILING > 1 static memo_t *live_memos[55]; # endif static inline int profile_memo_size_bucket(uint32_t dirty, uint32_t capacity) { if (capacity <= 16) return dirty; else if (capacity <= 32) return 17 + (capacity - 17) / 2; else if (capacity <= 64) return 25 + (capacity - 33) / 8; else return 29 + 26 - ffs_msb(capacity - 1); } static void profile_update_memo_dirty(memo_t *memo, uint32_t old_dirty, uint32_t new_dirty, uint32_t capacity) { if (capacity <= 16 && new_dirty != old_dirty) { ++memo_sizes[new_dirty]; ++live_memo_sizes[new_dirty]; live_memo_bytes[new_dirty] += capacity; --live_memo_sizes[old_dirty]; live_memo_bytes[old_dirty] -= capacity; # if HAVE_STRING_PROFILING > 1 if ((*memo->pprev = memo->next)) memo->next->pprev = memo->pprev; memo->pprev = &live_memos[new_dirty]; if ((memo->next = *memo->pprev)) memo->next->pprev = &memo->next; *memo->pprev = memo; # else (void) memo; # endif } } static void one_profile_report(StringAccum &sa, int i, int examples); #endif inline void assign_memo(const char *data, int length, memo_t *memo) const { _r.data = data; _r.length = length; if ((_r.memo = memo)) ++memo->refcount; } inline String(const char *data, int length, memo_t *memo) { assign_memo(data, length, memo); } inline void assign(const String &x) const { assign_memo(x._r.data, x._r.length, x._r.memo); } inline void deref() const { if (_r.memo && --_r.memo->refcount == 0) delete_memo(_r.memo); } void assign(const char *cstr, int len, bool need_deref); #if HAVE_PERMSTRING inline void assign(PermString x) const { assign_memo(x.c_str(), x.length(), 0); } #endif void assign_out_of_memory(); void append(const char *s, int len, memo_t *memo); static memo_t *create_memo(char *space, int dirty, int capacity); static void delete_memo(memo_t *memo); static const char null_data; static const char oom_data; static const char bool_data[11]; static const char int_data[20]; static const rep_t null_string_rep; static const rep_t oom_string_rep; static String make_claim(char *, int, int); // claim memory friend struct rep_t; friend class StringAccum; }; /** @relates String * @brief Compares two strings for equality. * * Returns true iff the two operands have the same lengths and the same * characters in the same order. At most one of the operands can be a * null-terminated C string. * @sa String::compare */ inline bool operator==(const String &a, const String &b) { return a.equals(b.data(), b.length()); } /** @relates String */ inline bool operator==(const char *a, const String &b) { return b.equals(a, -1); } /** @relates String */ inline bool operator==(const String &a, const char *b) { return a.equals(b, -1); } /** @relates String * @brief Compare two Strings for inequality. * * Returns true iff !(@a a == @a b). At most one of the operands can be a * null-terminated C string. */ inline bool operator!=(const String &a, const String &b) { return !a.equals(b.data(), b.length()); } /** @relates String */ inline bool operator!=(const char *a, const String &b) { return !b.equals(a, -1); } /** @relates String */ inline bool operator!=(const String &a, const char *b) { return !a.equals(b, -1); } /** @relates String * @brief Compare two Strings. * * Returns true iff @a a @< @a b in lexicographic order. * @sa String::compare */ inline bool operator<(const String &a, const String &b) { return a.compare(b.data(), b.length()) < 0; } /** @relates String * @brief Compare two Strings. * * Returns true iff @a a @<= @a b in lexicographic order. * @sa String::compare */ inline bool operator<=(const String &a, const String &b) { return a.compare(b.data(), b.length()) <= 0; } /** @relates String * @brief Compare two Strings. * * Returns true iff @a a @> @a b in lexicographic order. * @sa String::compare */ inline bool operator>(const String &a, const String &b) { return a.compare(b.data(), b.length()) > 0; } /** @relates String * @brief Compare two Strings. * * Returns true iff @a a @>= @a b in lexicographic order. * @sa String::compare */ inline bool operator>=(const String &a, const String &b) { return a.compare(b.data(), b.length()) >= 0; } /** @relates String * @brief Concatenate the operands and return the result. * * At most one of the two operands can be a null-terminated C string. */ inline String operator+(String a, const String &b) { a += b; return a; } /** @relates String */ inline String operator+(String a, const char *b) { a.append(b); return a; } /** @relates String */ inline String operator+(const char *a, const String &b) { String s1(a); s1 += b; return s1; } /** @relates String * @brief Concatenate the operands and return the result. * * The second operand is a single character. */ inline String operator+(String a, char b) { a.append(&b, 1); return a; } #if HAVE_PERMSTRING inline bool operator==(PermString a, const String &b) { return b.equals(a.c_str(), a.length()); } inline bool operator==(const String &a, PermString b) { return a.equals(b.c_str(), b.length()); } inline bool operator!=(PermString a, const String &b) { return !b.equals(a.c_str(), a.length()); } inline bool operator!=(const String &a, PermString b) { return !a.equals(b.c_str(), b.length()); } inline String operator+(String a, PermString b) { a.append(b.c_str(), b.length()); return a; } inline String operator+(PermString a, String b) { return String(a) + b; } inline String operator+(PermString a, const char *b) { return String(a) + b; } inline String operator+(const char *a, PermString b) { return String(a) + b; } inline String operator+(PermString a, PermString b) { return String(a) + b; } #endif inline hashcode_t hashcode(const String &str) { return str.hashcode(); } #endif lcdf-typetools-2.108/include/lcdf/vector.cc0000644000175000017500000001102113423375327015565 00000000000000#ifndef LCDF_VECTOR_CC #define LCDF_VECTOR_CC /* * vector.{cc,hh} -- simple array template class * Eddie Kohler * * Copyright (c) 1999-2000 Massachusetts Institute of Technology * Copyright (c) 2001-2003 International Computer Science Institute * Copyright (c) 1999-2019 Eddie Kohler * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file. These conditions include: you must * preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */ /* #include */ template Vector::Vector(const Vector &x) : _l(0), _n(0), _capacity(0) { *this = x; } template Vector::~Vector() { for (size_type i = 0; i < _n; i++) _l[i].~T(); delete[] (unsigned char *)_l; } template Vector & Vector::operator=(const Vector &o) { if (&o != this) { for (size_type i = 0; i < _n; i++) _l[i].~T(); #ifdef VALGRIND_MAKE_MEM_NOACCESS if (_l && _n) VALGRIND_MAKE_MEM_NOACCESS(_l, _n * sizeof(T)); #endif _n = 0; if (reserve(o._n)) { _n = o._n; #ifdef VALGRIND_MAKE_MEM_UNDEFINED if (_l && _n) VALGRIND_MAKE_MEM_UNDEFINED(_l, _n * sizeof(T)); #endif for (size_type i = 0; i < _n; i++) new(velt(i)) T(o._l[i]); } } return *this; } template Vector & Vector::assign(size_type n, const T &x) { if (&x >= begin() && &x < end()) { T x_copy(x); return assign(n, x_copy); } else { resize(0, x); resize(n, x); return *this; } } template typename Vector::iterator Vector::insert(iterator it, const T &x) { assert(it >= begin() && it <= end()); if (&x >= begin() && &x < end()) { T x_copy(x); return insert(it, x_copy); } if (_n == _capacity) { size_type pos = it - begin(); if (!reserve(RESERVE_GROW)) return end(); it = begin() + pos; } #ifdef VALGRIND_MAKE_MEM_UNDEFINED VALGRIND_MAKE_MEM_UNDEFINED(velt(_n), sizeof(T)); #endif for (iterator j = end(); j > it; ) { --j; new((void*) (j + 1)) T(*j); j->~T(); #ifdef VALGRIND_MAKE_MEM_UNDEFINED VALGRIND_MAKE_MEM_UNDEFINED(j, sizeof(T)); #endif } new((void*) it) T(x); _n++; return it; } template typename Vector::iterator Vector::erase(iterator a, iterator b) { if (b > a) { assert(a >= begin() && b <= end()); iterator i = a, j = b; for (; j < end(); i++, j++) { i->~T(); #ifdef VALGRIND_MAKE_MEM_UNDEFINED VALGRIND_MAKE_MEM_UNDEFINED(i, sizeof(T)); #endif new((void*) i) T(*j); } for (; i < end(); i++) i->~T(); _n -= b - a; #ifdef VALGRIND_MAKE_MEM_NOACCESS VALGRIND_MAKE_MEM_NOACCESS(_l + _n, (b - a) * sizeof(T)); #endif return a; } else return b; } template bool Vector::reserve_and_push_back(size_type want, const T *push_x) { if (push_x && push_x >= begin() && push_x < end()) { T x_copy(*push_x); return reserve_and_push_back(want, &x_copy); } if (want < 0) want = (_capacity > 0 ? _capacity * 2 : 4); if (want > _capacity) { T *new_l = (T *)new unsigned char[sizeof(T) * want]; if (!new_l) return false; #ifdef VALGRIND_MAKE_MEM_NOACCESS VALGRIND_MAKE_MEM_NOACCESS(new_l + _n, (want - _n) * sizeof(T)); #endif for (size_type i = 0; i < _n; i++) { new(velt(new_l, i)) T(_l[i]); _l[i].~T(); } delete[] (unsigned char *)_l; _l = new_l; _capacity = want; } if (push_x) push_back(*push_x); return true; } template void Vector::resize(size_type n, const T &x) { if (&x >= begin() && &x < end()) { T x_copy(x); resize(n, x_copy); } else if (n <= _capacity || reserve(n)) { for (size_type i = n; i < _n; i++) _l[i].~T(); #ifdef VALGRIND_MAKE_MEM_NOACCESS if (n < _n) VALGRIND_MAKE_MEM_NOACCESS(_l + n, (_n - n) * sizeof(T)); if (_n < n) VALGRIND_MAKE_MEM_UNDEFINED(_l + _n, (n - _n) * sizeof(T)); #endif for (size_type i = _n; i < n; i++) new(velt(i)) T(x); _n = n; } } template void Vector::swap(Vector &x) { T *l = _l; _l = x._l; x._l = l; size_type n = _n; _n = x._n; x._n = n; size_type cap = _capacity; _capacity = x._capacity; x._capacity = cap; } #endif lcdf-typetools-2.108/include/lcdf/straccum.hh0000644000175000017500000004447713423375327016143 00000000000000// -*- related-file-name: "../../liblcdf/straccum.cc" -*- #ifndef LCDF_STRACCUM_HH #define LCDF_STRACCUM_HH #include #include #include #if HAVE_PERMSTRING # include #endif #if __GNUC__ > 4 # define LCDF_SNPRINTF_ATTR __attribute__((__format__(__printf__, 3, 4))) #else # define LCDF_SNPRINTF_ATTR /* nothing */ #endif template class Vector; /** @file @brief Click's StringAccum class, used to construct Strings efficiently from pieces. */ class StringAccum { public: typedef const char* const_iterator; typedef char* iterator; typedef int (StringAccum::*unspecified_bool_type)() const; inline StringAccum(); explicit inline StringAccum(int capacity); explicit inline StringAccum(const char *cstr); inline StringAccum(const char* s, int len); inline StringAccum(const String& str); inline StringAccum(const StringAccum& x); inline ~StringAccum(); inline const char* data() const; inline char* data(); inline const unsigned char* udata() const; inline unsigned char* udata(); inline int length() const; inline int capacity() const; inline bool empty() const; inline bool operator!() const; inline bool out_of_memory() const; inline const_iterator begin() const; inline iterator begin(); inline const_iterator end() const; inline iterator end(); /** @brief Return true iff the StringAccum contains characters. * * Returns false for empty and out-of-memory StringAccums. */ inline operator unspecified_bool_type() const { return _len != 0 ? &StringAccum::capacity : 0; } /** @brief Null-terminate this StringAccum and return its data. * * Note that the null character does not contribute to the StringAccum's * length(), and later append() and similar operations can overwrite it. * If appending the null character fails, the StringAccum becomes * out-of-memory and the returned value is a null string. */ const char *c_str(); inline char operator[](int i) const; inline char& operator[](int i); inline char front() const; inline char& front(); inline char back() const; inline char& back(); inline void clear(); inline char* reserve(int n); inline void set_length(int len); /** @brief Set the StringAccum's length to @a len. * @pre @a len >= 0 * @return 0 on success, -ENOMEM on failure */ int resize(int len); inline void adjust_length(int delta); inline char* extend(int nadjust, int nreserve = 0); inline void pop_back(int n = 1); inline void append(char c); inline void append(unsigned char c); /** @brief Append @a len copies of character @a c to the StringAccum. */ void append_fill(int c, int len); inline void append_utf8(unsigned ch); /** @brief Append the null-terminated C string @a s to this StringAccum. * @param s data to append */ void append(const char* s); inline void append(const char* s, int len); inline void append(const unsigned char* s, int len); inline void append(const char* begin, const char* end); inline void append(const unsigned char* begin, const unsigned char* end); // word joining void append_break_lines(const String &text, int linelen, const String &leftmargin = String()); /** @brief Append result of snprintf() to this StringAccum. * @param n maximum number of characters to print * @param format format argument to snprintf() * * The terminating null character is not appended to the string. * * @note The safe vsnprintf() variant is called if it exists. It does in * the Linux kernel, and on modern Unix variants. However, if it does not * exist on your machine, then this function is actually unsafe, and you * should make sure that the printf() invocation represented by your * arguments will never write more than @a n characters, not including the * terminating null. */ StringAccum &snprintf(int n, const char *format, ...) LCDF_SNPRINTF_ATTR; /** @brief Return a String object with this StringAccum's contents. * * This operation donates the StringAccum's memory to the returned String. * After a call to take_string(), the StringAccum object becomes empty, * and any future append() operations may cause memory allocations. If * the StringAccum is out-of-memory, the returned String is also * out-of-memory, but the StringAccum's out-of-memory state is reset. */ String take_string(); inline StringAccum& operator=(const StringAccum& x); /** @brief Swap this StringAccum's contents with @a x. */ void swap(StringAccum &x); // see also operator<< declarations below private: enum { MEMO_SPACE = String::MEMO_SPACE }; unsigned char *_s; int _len; int _cap; char *grow(int); void assign_out_of_memory(); char *hard_extend(int nadjust, int nreserve); void hard_append(const char *s, int len); void append_utf8_hard(unsigned ch); friend StringAccum &operator<<(StringAccum &sa, const char *s); friend StringAccum &operator<<(StringAccum &sa, const String &str); #if HAVE_PERMSTRING friend StringAccum &operator<<(StringAccum &sa, PermString s); #endif }; inline StringAccum &operator<<(StringAccum &, char); inline StringAccum &operator<<(StringAccum &, unsigned char); inline StringAccum &operator<<(StringAccum &, const char *); inline StringAccum &operator<<(StringAccum &, const String &); inline StringAccum &operator<<(StringAccum &, const StringAccum &); #ifdef HAVE_PERMSTRING inline StringAccum &operator<<(StringAccum &, PermString); #endif inline StringAccum &operator<<(StringAccum &, bool); inline StringAccum &operator<<(StringAccum &, short); inline StringAccum &operator<<(StringAccum &, unsigned short); inline StringAccum &operator<<(StringAccum &, int); inline StringAccum &operator<<(StringAccum &, unsigned); StringAccum &operator<<(StringAccum &, long); StringAccum &operator<<(StringAccum &, unsigned long); StringAccum &operator<<(StringAccum &, double); /** @brief Construct an empty StringAccum (with length 0). */ inline StringAccum::StringAccum() : _s(0), _len(0), _cap(0) { } /** @brief Construct a StringAccum with room for at least @a capacity * characters. * @param capacity initial capacity * * If @a capacity <= 0, the StringAccum is created empty. If @a capacity * is too large (so that @a capacity bytes of memory can't be allocated), * the StringAccum falls back to a smaller capacity (possibly zero). */ inline StringAccum::StringAccum(int capacity) : _len(0) { assert(capacity >= 0); if (capacity && (_s = new unsigned char[capacity + MEMO_SPACE])) { _s += MEMO_SPACE; _cap = capacity; } else { _s = 0; _cap = 0; } } /** @brief Construct a StringAccum containing the characters in @a s. */ inline StringAccum::StringAccum(const char *cstr) : _s(0), _len(0), _cap(0) { append(cstr); } /** @brief Construct a StringAccum containing the characters in @a s. */ inline StringAccum::StringAccum(const char *s, int len) : _s(0), _len(0), _cap(0) { append(s, len); } /** @brief Construct a StringAccum containing the characters in @a str. */ inline StringAccum::StringAccum(const String &str) : _s(0), _len(0), _cap(0) { append(str.begin(), str.end()); } /** @brief Construct a StringAccum containing a copy of @a x. */ inline StringAccum::StringAccum(const StringAccum &x) : _s(0), _len(0), _cap(0) { append(x.data(), x.length()); } /** @brief Destroy a StringAccum, freeing its memory. */ inline StringAccum::~StringAccum() { if (_cap > 0) delete[] (_s - MEMO_SPACE); } /** @brief Return the contents of the StringAccum. * @return The StringAccum's contents. * * The return value is null if the StringAccum is empty or out-of-memory. * The returned data() value points to writable memory (unless the * StringAccum itself is const). */ inline const char* StringAccum::data() const { return reinterpret_cast(_s); } /** @overload */ inline char* StringAccum::data() { return reinterpret_cast(_s); } inline const unsigned char* StringAccum::udata() const { return _s; } inline unsigned char* StringAccum::udata() { return _s; } /** @brief Return true iff the StringAccum is empty or out-of-memory. */ inline bool StringAccum::empty() const { return _len == 0; } /** @brief Return the length of the StringAccum. */ inline int StringAccum::length() const { return _len; } /** @brief Return the StringAccum's current capacity. * * The capacity is the maximum length the StringAccum can hold without * incurring a memory allocation. Returns -1 for out-of-memory * StringAccums. */ inline int StringAccum::capacity() const { return _cap; } /** @brief Return an iterator for the first character in the StringAccum. * * StringAccum iterators are simply pointers into string data, so they are * quite efficient. @sa StringAccum::data */ inline StringAccum::const_iterator StringAccum::begin() const { return reinterpret_cast(_s); } /** @overload */ inline StringAccum::iterator StringAccum::begin() { return reinterpret_cast(_s); } /** @brief Return an iterator for the end of the StringAccum. * * The return value points one character beyond the last character in the * StringAccum. */ inline StringAccum::const_iterator StringAccum::end() const { return reinterpret_cast(_s + _len); } /** @overload */ inline StringAccum::iterator StringAccum::end() { return reinterpret_cast(_s + _len); } /** @brief Return true iff the StringAccum does not contain characters. * * Returns true for empty and out-of-memory StringAccums. */ inline bool StringAccum::operator!() const { return _len == 0; } /** @brief Return true iff the StringAccum is out-of-memory. */ inline bool StringAccum::out_of_memory() const { return _cap < 0; } /** @brief Return the ith character in the string. * @param i character index * @pre 0 <= @a i < length() */ inline char StringAccum::operator[](int i) const { assert((unsigned) i < (unsigned) _len); return static_cast(_s[i]); } /** @brief Return a reference to the ith character in the string. * @param i character index * @pre 0 <= @a i < length() */ inline char& StringAccum::operator[](int i) { assert((unsigned) i < (unsigned) _len); return reinterpret_cast(_s[i]); } /** @brief Return the first character in the string. * @pre length() > 0 */ inline char StringAccum::front() const { assert(_len > 0); return static_cast(_s[0]); } /** @brief Return a reference to the first character in the string. * @pre length() > 0 */ inline char& StringAccum::front() { assert(_len > 0); return reinterpret_cast(_s[0]); } /** @brief Return the last character in the string. * @pre length() > 0 */ inline char StringAccum::back() const { assert(_len > 0); return static_cast(_s[_len - 1]); } /** @brief Return a reference to the last character in the string. * @pre length() > 0 */ inline char& StringAccum::back() { assert(_len > 0); return reinterpret_cast(_s[_len - 1]); } /** @brief Clear the StringAccum's comments. * * All characters in the StringAccum are erased. Also resets the * StringAccum's out-of-memory status. */ inline void StringAccum::clear() { if (_cap < 0) { _cap = 0; _s = 0; } _len = 0; } /** @brief Reserve space for at least @a n characters. * @return a pointer to at least @a n characters, or null if allocation * fails * @pre @a n >= 0 * * reserve() does not change the string's length(), only its capacity(). * In a frequent usage pattern, code calls reserve(), passing an upper * bound on the characters that could be written by a series of * operations. After writing into the returned buffer, adjust_length() is * called to account for the number of characters actually written. * * On failure, null is returned and errno is set to ENOMEM. */ inline char* StringAccum::reserve(int n) { assert(n >= 0); if (_len + n <= _cap) return reinterpret_cast(_s + _len); else return grow(_len + n); } /** @brief Set the StringAccum's length to @a len. * @param len new length in characters * @pre 0 <= @a len <= capacity() * @sa adjust_length */ inline void StringAccum::set_length(int len) { assert(len >= 0 && _len <= _cap); _len = len; } /** @brief Adjust the StringAccum's length. * @param delta length adjustment * @pre If @a delta > 0, then length() + @a delta <= capacity(). * If @a delta < 0, then length() + delta >= 0. * * The StringAccum's length after adjust_length(@a delta) equals its old * length plus @a delta. Generally adjust_length() is used after a call * to reserve(). @sa set_length */ inline void StringAccum::adjust_length(int delta) { assert(_len + delta >= 0 && _len + delta <= _cap); _len += delta; } /** @brief Reserve space and adjust length in one operation. * @param nadjust number of characters to reserve and adjust length * @param nreserve additional characters to reserve * @pre @a nadjust >= 0 and @a nreserve >= 0 * * This operation combines the effects of reserve(@a nadjust + @a * nreserve) and adjust_length(@a nadjust). Returns the result of the * reserve() call. */ inline char* StringAccum::extend(int nadjust, int nreserve) { assert(nadjust >= 0 && nreserve >= 0); if (_len + nadjust + nreserve <= _cap) { char *x = reinterpret_cast(_s + _len); _len += nadjust; return x; } else return hard_extend(nadjust, nreserve); } /** @brief Remove characters from the end of the StringAccum. * @param n number of characters to remove * @pre @a n >= 0 and @a n <= length() * * Same as adjust_length(-@a n). */ inline void StringAccum::pop_back(int n) { assert(n >= 0 && _len >= n); _len -= n; } /** @brief Append character @a c to the StringAccum. * @param c character to append */ inline void StringAccum::append(char c) { if (_len < _cap || grow(_len)) _s[_len++] = c; } /** @overload */ inline void StringAccum::append(unsigned char c) { append(static_cast(c)); } /** @brief Append the UTF-8 encoding of Unicode character @a ch. */ inline void StringAccum::append_utf8(unsigned ch) { if (ch < 0x80) append((unsigned char) ch); else append_utf8_hard(ch); } /** @brief Append the first @a len characters of @a s to this StringAccum. * @param s data to append * @param len length of data * @pre @a len >= 0 */ inline void StringAccum::append(const char* s, int len) { assert(len >= 0); if (_len + len <= _cap) { memcpy(_s + _len, s, len); _len += len; } else hard_append(s, len); } /** @overload */ inline void StringAccum::append(const unsigned char* s, int len) { append(reinterpret_cast(s), len); } /** @brief Append the data from @a begin to @a end to the end of this * StringAccum. * * Does nothing if @a begin >= @a end. */ inline void StringAccum::append(const char* begin, const char* end) { if (begin < end) append(begin, end - begin); } /** @overload */ inline void StringAccum::append(const unsigned char* begin, const unsigned char* end) { if (begin < end) append(begin, end - begin); } /** @brief Assign this StringAccum to @a x. */ inline StringAccum& StringAccum::operator=(const StringAccum& x) { if (&x != this) { if (out_of_memory()) _s = 0, _cap = 0; _len = 0; append(x.data(), x.length()); } return *this; } /** @relates StringAccum @brief Append character @a c to StringAccum @a sa. @return @a sa @note Same as @a sa.append(@a c). */ inline StringAccum & operator<<(StringAccum &sa, char c) { sa.append(c); return sa; } /** @relates StringAccum @brief Append character @a c to StringAccum @a sa. @return @a sa @note Same as @a sa.append(@a c). */ inline StringAccum & operator<<(StringAccum &sa, unsigned char c) { sa.append(c); return sa; } /** @relates StringAccum @brief Append null-terminated C string @a cstr to StringAccum @a sa. @return @a sa @note Same as @a sa.append(@a cstr). */ inline StringAccum & operator<<(StringAccum &sa, const char *cstr) { sa.append(cstr); return sa; } /** @relates StringAccum @brief Append "true" or "false" to @a sa, depending on @a b. @return @a sa */ inline StringAccum & operator<<(StringAccum &sa, bool b) { static const char truefalse[] = "truefalse"; if (b) sa.append(truefalse, 4); else sa.append(truefalse + 4, 5); return sa; } /** @relates StringAccum @brief Append decimal representation of @a i to @a sa. @return @a sa */ inline StringAccum & operator<<(StringAccum &sa, short i) { return sa << static_cast(i); } /** @relates StringAccum @brief Append decimal representation of @a u to @a sa. @return @a sa */ inline StringAccum & operator<<(StringAccum &sa, unsigned short u) { return sa << static_cast(u); } /** @relates StringAccum @brief Append decimal representation of @a i to @a sa. @return @a sa */ inline StringAccum & operator<<(StringAccum &sa, int i) { return sa << static_cast(i); } /** @relates StringAccum @brief Append decimal representation of @a u to @a sa. @return @a sa */ inline StringAccum & operator<<(StringAccum &sa, unsigned u) { return sa << static_cast(u); } /** @relates StringAccum @brief Append the contents of @a str to @a sa. @return @a sa */ inline StringAccum & operator<<(StringAccum &sa, const String &str) { if (!str.out_of_memory()) sa.hard_append(str.begin(), str.length()); else sa.assign_out_of_memory(); return sa; } #ifdef HAVE_PERMSTRING inline StringAccum & operator<<(StringAccum &sa, PermString s) { sa.append(s.c_str(), s.length()); return sa; } #endif /** @relates StringAccum @brief Append the contents of @a sb to @a sa. @return @a sa */ inline StringAccum & operator<<(StringAccum &sa, const StringAccum &sb) { sa.append(sb.begin(), sb.end()); return sa; } inline bool operator==(StringAccum &sa, const char *s) { return strcmp(sa.c_str(), s) == 0; } inline bool operator!=(StringAccum &sa, const char *s) { return strcmp(sa.c_str(), s) != 0; } #undef LCDF_SNPRINTF_ATTR #endif lcdf-typetools-2.108/include/lcdf/clp.h0000644000175000017500000002416513423375327014720 00000000000000/* -*- related-file-name: "../../liblcdf/clp.c" -*- */ #ifndef LCDF_CLP_H #define LCDF_CLP_H #ifdef __cplusplus extern "C" { #endif /* clp.h - Public interface to CLP. * This file is part of CLP, the command line parser package. * * Copyright (c) 1997-2019 Eddie Kohler, ekohler@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file, which is available in full at * http://www.pdos.lcs.mit.edu/click/license.html. The conditions include: you * must preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */ typedef struct Clp_Option Clp_Option; typedef struct Clp_Parser Clp_Parser; typedef struct Clp_ParserState Clp_ParserState; /** @brief Option description. * * CLP users declare arrays of Clp_Option structures to specify what options * should be parsed. * @sa Clp_NewParser, Clp_SetOptions */ struct Clp_Option { const char *long_name; /**< Name of long option, or NULL if the option has no long name. */ int short_name; /**< Character defining short option, or 0 if the option has no short name. */ int option_id; /**< User-specified ID defining option, returned by Clp_Next. */ int val_type; /**< ID of option's value type, or 0 if option takes no value. */ int flags; /**< Option parsing flags. */ }; /** @name Value types * These values describe the type of an option's argument and are used in * the Clp_Option val_type field. For example, if an option took integers, its * Clp_Option structure would have val_type set to Clp_ValInt. */ /**@{*/ #define Clp_NoVal 0 /**< @brief Option takes no value. */ #define Clp_ValString 1 /**< @brief Option value is an arbitrary string. */ #define Clp_ValStringNotOption 2 /**< @brief Option value is a non-option string. See Clp_DisallowOptions. */ #define Clp_ValBool 3 /**< @brief Option value is a boolean. Accepts "true", "false", "yes", "no", "1", and "0", or any prefixes thereof. The match is case-insensitive. */ #define Clp_ValInt 4 /**< @brief Option value is a signed int. Accepts an optional "+" or "-" sign, followed by one or more digits. The digits may be include a "0x" or "0X" prefix, for a hexidecimal number, or a "0" prefix, for an octal number; otherwise it is decimal. */ #define Clp_ValUnsigned 5 /**< @brief Option value is an unsigned int. Accepts an optional "+" sign, followed by one or more digits. The digits may be include a "0x" or "0X" prefix, for a hexidecimal number, or a "0" prefix, for an octal number; otherwise it is decimal. */ #define Clp_ValDouble 6 /**< @brief Option value is a double. Accepts a real number as defined by strtod(). */ #define Clp_ValFirstUser 10 /**< @brief Value types >= Clp_ValFirstUser are available for user types. */ /**@}*/ /** @name Option flags * These flags are used in the Clp_Option flags field. */ /**@{*/ #define Clp_Mandatory (1<<0) /**< @brief Option flag: value is mandatory. It is an error if the option has no value. This is the default if an option has arg_type != 0 and the Clp_Optional flag is not provided. */ #define Clp_Optional (1<<1) /**< @brief Option flag: value is optional. */ #define Clp_Negate (1<<2) /**< @brief Option flag: option may be negated. --no-[long_name] will be accepted in argument lists. */ #define Clp_OnlyNegated (1<<3) /**< @brief Option flag: option must be negated. --no-[long_name] will be accepted in argument lists, but --[long_name] will not. This is the default if long_name begins with "no-". */ #define Clp_PreferredMatch (1<<4) /**< @brief Option flag: prefer this option when matching. Prefixes of --[long_name] should map to this option, even if other options begin with --[long_name]. */ /**@}*/ /** @name Option character types * These flags are used in to define character types in Clp_SetOptionChar(). */ /**@{*/ /* Clp_NotOption 0 */ #define Clp_Short (1<<0) /**< @brief Option character begins a set of short options. */ #define Clp_Long (1<<1) /**< @brief Option character begins a long option. */ #define Clp_ShortNegated (1<<2) /**< @brief Option character begins a set of negated short options. */ #define Clp_LongNegated (1<<3) /**< @brief Option character begins a negated long option. */ #define Clp_LongImplicit (1<<4) /**< @brief Option character can begin a long option, and is part of that long option. */ /**@}*/ #define Clp_NotOption 0 /**< @brief Clp_Next value: argument was not an option. */ #define Clp_Done -1 /**< @brief Clp_Next value: there are no more arguments. */ #define Clp_BadOption -2 /**< @brief Clp_Next value: argument was an erroneous option. */ #define Clp_Error -3 /**< @brief Clp_Next value: internal CLP error. */ #define Clp_ValSize 40 /**< @brief Minimum size of the Clp_Parser val.cs field. */ #define Clp_ValIntSize 10 /**< @brief Minimum size of the Clp_Parser val.is field. */ /** @brief A value parsing function. * @param clp the parser * @param vstr the value to be parsed * @param complain if nonzero, report error messages via Clp_OptionError * @param user_data user data passed to Clp_AddType() * @return 1 if parsing succeeded, 0 otherwise */ typedef int (*Clp_ValParseFunc)(Clp_Parser *clp, const char *vstr, int complain, void *user_data); /** @brief A function for reporting option errors. * @param clp the parser * @param message error message */ typedef void (*Clp_ErrorHandler)(Clp_Parser *clp, const char *message); /** @brief Command line parser. * * A Clp_Parser object defines an instance of CLP, including allowed options, * value types, and current arguments. * @sa Clp_NewParser, Clp_SetOptions, Clp_SetArguments */ struct Clp_Parser { const Clp_Option *option; /**< The last option. */ int negated; /**< Whether the last option was negated. */ int have_val; /**< Whether the last option had a value. */ const char *vstr; /**< The string value provided with the last option. */ union { int i; unsigned u; double d; const char *s; void *pv; #ifdef HAVE_INT64_TYPES int64_t i64; uint64_t u64; #endif char cs[Clp_ValSize]; unsigned char ucs[Clp_ValSize]; int is[Clp_ValIntSize]; unsigned us[Clp_ValIntSize]; } val; /**< The parsed value provided with the last option. */ void *user_data; /**< Uninterpreted by CLP; users can set arbitrarily. */ struct Clp_Internal *internal; }; /** @cond never */ #if __GNUC__ >= 4 # define CLP_SENTINEL __attribute__((sentinel)) #else # define CLP_SENTINEL /* nothing */ #endif /** @endcond never */ /** @brief Create a new Clp_Parser. */ Clp_Parser *Clp_NewParser(int argc, const char * const *argv, int nopt, const Clp_Option *opt); /** @brief Destroy a Clp_Parser object. */ void Clp_DeleteParser(Clp_Parser *clp); /** @brief Return @a clp's program name. */ const char *Clp_ProgramName(Clp_Parser *clp); /** @brief Set @a clp's program name. */ const char *Clp_SetProgramName(Clp_Parser *clp, const char *name); /** @brief Set @a clp's error handler function. */ Clp_ErrorHandler Clp_SetErrorHandler(Clp_Parser *clp, Clp_ErrorHandler errh); /** @brief Set @a clp's UTF-8 mode. */ int Clp_SetUTF8(Clp_Parser *clp, int utf8); /** @brief Return @a clp's treatment of character @a c. */ int Clp_OptionChar(Clp_Parser *clp, int c); /** @brief Set @a clp's treatment of character @a c. */ int Clp_SetOptionChar(Clp_Parser *clp, int c, int type); /** @brief Set @a clp's option definitions. */ int Clp_SetOptions(Clp_Parser *clp, int nopt, const Clp_Option *opt); /** @brief Set @a clp's arguments. */ void Clp_SetArguments(Clp_Parser *clp, int argc, const char * const *argv); /** @brief Set whether @a clp is searching for options. */ int Clp_SetOptionProcessing(Clp_Parser *clp, int on); #define Clp_DisallowOptions (1<<0) /**< @brief Value type flag: value can't be an option string. See Clp_AddType(). */ /** @brief Define a new value type for @a clp. */ int Clp_AddType(Clp_Parser *clp, int val_type, int flags, Clp_ValParseFunc parser, void *user_data); #define Clp_AllowNumbers (1<<0) /**< @brief String list flag: allow explicit numbers. See Clp_AddStringListType() and Clp_AddStringListTypeVec(). */ /** @brief Define a new string list value type for @a clp. */ int Clp_AddStringListTypeVec(Clp_Parser *clp, int val_type, int flags, int nstrs, const char * const *strs, const int *vals); /** @brief Define a new string list value type for @a clp. */ int Clp_AddStringListType(Clp_Parser *clp, int val_type, int flags, ...) CLP_SENTINEL; /** @brief Parse and return the next argument from @a clp. */ int Clp_Next(Clp_Parser *clp); /** @brief Return the next argument from @a clp without option parsing. */ const char *Clp_Shift(Clp_Parser *clp, int allow_options); /** @brief Create a new Clp_ParserState. */ Clp_ParserState *Clp_NewParserState(void); /** @brief Destroy a Clp_ParserState object. */ void Clp_DeleteParserState(Clp_ParserState *state); /** @brief Save @a clp's current state in @a state. */ void Clp_SaveParser(const Clp_Parser *clp, Clp_ParserState *state); /** @brief Restore parser state from @a state into @a clp. */ void Clp_RestoreParser(Clp_Parser *clp, const Clp_ParserState *state); /** @brief Report a parser error. */ int Clp_OptionError(Clp_Parser *clp, const char *format, ...); /** @brief Extract the current option as a string. */ int Clp_CurOptionNameBuf(Clp_Parser *clp, char *buf, int len); /** @brief Extract the current option as a string. */ const char *Clp_CurOptionName(Clp_Parser *clp); #undef CLP_SENTINEL #ifdef __cplusplus } #endif #endif lcdf-typetools-2.108/include/lcdf/hashmap.hh0000664000175000017500000001167112732752520015727 00000000000000#ifndef LCDF_HASHMAP_HH #define LCDF_HASHMAP_HH #include #include // K AND V REQUIREMENTS: // // K::K() // K::operator bool() const // Must have (bool)(K()) == false // and no k with (bool)k == false is stored. // K & K::operator=(const K &) // k1 == k2 // hashcode_t hashcode(const K &) // If hashcode(k1) != hashcode(k2), then k1 != k2. // Actually any unsigned integer type may be used. // // V::V() // V & V::operator=(const V &) template class _HashMap_const_iterator; template class _HashMap_iterator; template class HashMap { public: HashMap(); explicit HashMap(const V &); HashMap(const HashMap &); ~HashMap() { delete[] _e; } int size() const { return _n; } bool empty() const { return _n == 0; } int capacity() const { return _capacity; } const V &default_value() const { return _default_value; } void set_default_value(const V &v) { _default_value = v; } typedef _HashMap_const_iterator const_iterator; typedef _HashMap_iterator iterator; inline const_iterator begin() const; inline iterator begin(); inline const_iterator end() const; inline iterator end(); inline const V &find(const K &) const; inline V *findp(const K &) const; inline const V &operator[](const K &k) const; V &find_force(const K &, const V &); inline V &find_force(const K &); bool insert(const K &, const V &); void clear(); HashMap &operator=(const HashMap &); void swap(HashMap &); void resize(int size) { increase(size); } struct Pair { K key; V value; Pair() : key(), value() { } }; private: int _capacity; int _grow_limit; int _n; Pair *_e; V _default_value; void increase(int); inline void check_capacity(); inline int bucket(const K &) const; friend class _HashMap_const_iterator; friend class _HashMap_iterator; }; template class _HashMap_const_iterator { public: typedef _HashMap_const_iterator const_iterator; typedef typename HashMap::Pair Pair; operator bool() const { return _pos < _hm->_capacity; } bool operator!() const { return _pos >= _hm->_capacity; } void operator++(int); void operator++() { (*this)++; } const K &key() const { return _hm->_e[_pos].key; } const V &value() const { return _hm->_e[_pos].value; } const Pair &pair() const { return _hm->_e[_pos]; } inline bool operator==(const const_iterator &) const; inline bool operator!=(const const_iterator &) const; private: const HashMap *_hm; int _pos; _HashMap_const_iterator(const HashMap *, int); friend class HashMap; friend class _HashMap_iterator; }; template class _HashMap_iterator : public _HashMap_const_iterator { public: typedef _HashMap_iterator iterator; V &value() const { return this->_hm->_e[this->_pos].value; } private: _HashMap_iterator(const HashMap *hm, int pos) : _HashMap_const_iterator(hm, pos) { } friend class HashMap; }; template inline int HashMap::bucket(const K &key) const { assert(key); hashcode_t hc = hashcode(key); int i = hc & (_capacity - 1); int j = ((hc >> 6) & (_capacity - 1)) | 1; while (_e[i].key && !(_e[i].key == key)) i = (i + j) & (_capacity - 1); return i; } template inline const V & HashMap::find(const K &key) const { int i = bucket(key); const V *v = (_e[i].key ? &_e[i].value : &_default_value); return *v; } template inline const V & HashMap::operator[](const K &key) const { return find(key); } template inline V * HashMap::findp(const K &key) const { int i = bucket(key); return _e[i].key ? &_e[i].value : 0; } template inline V & HashMap::find_force(const K &key) { return find_force(key, _default_value); } template inline _HashMap_const_iterator HashMap::begin() const { return const_iterator(this, 0); } template inline _HashMap_const_iterator HashMap::end() const { return const_iterator(this, _capacity); } template inline _HashMap_iterator HashMap::begin() { return iterator(this, 0); } template inline _HashMap_iterator HashMap::end() { return iterator(this, _capacity); } template inline bool _HashMap_const_iterator::operator==(const const_iterator &i) const { return _hm == i._hm && _pos == i._pos; } template inline bool _HashMap_const_iterator::operator!=(const const_iterator &i) const { return _hm != i._hm || _pos != i._pos; } #include // necessary to support GCC 3.3 #endif lcdf-typetools-2.108/include/lcdf/inttypes.h0000664000175000017500000000144112732752520016007 00000000000000#ifndef LCDF_INTTYPES_H #define LCDF_INTTYPES_H /* Define known-width integer types. */ #ifdef HAVE_INTTYPES_H # include #elif defined(HAVE_SYS_TYPES_H) # include # ifdef HAVE_U_INT_TYPES typedef u_int8_t uint8_t; typedef u_int16_t uint16_t; typedef u_int32_t uint32_t; # endif #endif #ifdef HAVE_FAKE_INT_TYPES typedef signed char int8_t; typedef unsigned char uint8_t; typedef signed short int16_t; typedef unsigned short uint16_t; typedef signed int int32_t; typedef unsigned int uint32_t; #endif #ifndef HAVE_UINTPTR_T # if SIZEOF_VOID_P == SIZEOF_UNSIGNED_INT typedef unsigned int uintptr_t; # elif SIZEOF_VOID_P == SIZEOF_UNSIGNED_LONG typedef unsigned long uintptr_t; # endif #endif /* Note: Windows compilers call these types '[un]signed __int8', etc. */ #endif lcdf-typetools-2.108/include/lcdf/filename.hh0000664000175000017500000000204012732752520016054 00000000000000// -*- related-file-name: "../../liblcdf/filename.cc" -*- #ifndef LCDF_FILENAME_HH #define LCDF_FILENAME_HH #include #include class Filename { public: Filename() : _dir("."), _actual(0) { } Filename(const String &); Filename(const String &dir, const String &name); Filename(FILE *, const String &fake_name); bool fake() const { return _actual != 0; } const String &directory() const { return _dir; } const String &name() const { return _name; } const String &path() const { return _path; } String base() const; String extension() const; operator bool() const { return _name; } bool operator!() const { return !_name; } FILE *open_read(bool binary = false) const; bool readable() const; FILE *open_write(bool binary = false) const; Filename from_directory(const String &n) const { return Filename(_dir, n);} private: mutable String _dir; // mutable for c_str() mutable String _name; mutable String _path; FILE *_actual; }; #endif lcdf-typetools-2.108/include/lcdf/strtonum.h0000664000175000017500000000016112732752520016021 00000000000000#ifdef __cplusplus extern "C" { #endif double strtonumber(const char *, char **); #ifdef __cplusplus } #endif lcdf-typetools-2.108/glyphlist.txt0000664000175000017500000022653212732752520014216 00000000000000# ----------------------------------------------------------- # Copyright 2002, 2010, 2015 Adobe Systems Incorporated. # # 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.html # # 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. # ----------------------------------------------------------- # Name: Adobe Glyph List # Table version: 2.0 # Date: September 20, 2002 # URL: https://github.com/adobe-type-tools/agl-aglfn # # Format: two semicolon-delimited fields: # (1) glyph name--upper/lowercase letters and digits # (2) Unicode scalar value--four uppercase hexadecimal digits # A;0041 AE;00C6 AEacute;01FC AEmacron;01E2 AEsmall;F7E6 Aacute;00C1 Aacutesmall;F7E1 Abreve;0102 Abreveacute;1EAE Abrevecyrillic;04D0 Abrevedotbelow;1EB6 Abrevegrave;1EB0 Abrevehookabove;1EB2 Abrevetilde;1EB4 Acaron;01CD Acircle;24B6 Acircumflex;00C2 Acircumflexacute;1EA4 Acircumflexdotbelow;1EAC Acircumflexgrave;1EA6 Acircumflexhookabove;1EA8 Acircumflexsmall;F7E2 Acircumflextilde;1EAA Acute;F6C9 Acutesmall;F7B4 Acyrillic;0410 Adblgrave;0200 Adieresis;00C4 Adieresiscyrillic;04D2 Adieresismacron;01DE Adieresissmall;F7E4 Adotbelow;1EA0 Adotmacron;01E0 Agrave;00C0 Agravesmall;F7E0 Ahookabove;1EA2 Aiecyrillic;04D4 Ainvertedbreve;0202 Alpha;0391 Alphatonos;0386 Amacron;0100 Amonospace;FF21 Aogonek;0104 Aring;00C5 Aringacute;01FA Aringbelow;1E00 Aringsmall;F7E5 Asmall;F761 Atilde;00C3 Atildesmall;F7E3 Aybarmenian;0531 B;0042 Bcircle;24B7 Bdotaccent;1E02 Bdotbelow;1E04 Becyrillic;0411 Benarmenian;0532 Beta;0392 Bhook;0181 Blinebelow;1E06 Bmonospace;FF22 Brevesmall;F6F4 Bsmall;F762 Btopbar;0182 C;0043 Caarmenian;053E Cacute;0106 Caron;F6CA Caronsmall;F6F5 Ccaron;010C Ccedilla;00C7 Ccedillaacute;1E08 Ccedillasmall;F7E7 Ccircle;24B8 Ccircumflex;0108 Cdot;010A Cdotaccent;010A Cedillasmall;F7B8 Chaarmenian;0549 Cheabkhasiancyrillic;04BC Checyrillic;0427 Chedescenderabkhasiancyrillic;04BE Chedescendercyrillic;04B6 Chedieresiscyrillic;04F4 Cheharmenian;0543 Chekhakassiancyrillic;04CB Cheverticalstrokecyrillic;04B8 Chi;03A7 Chook;0187 Circumflexsmall;F6F6 Cmonospace;FF23 Coarmenian;0551 Csmall;F763 D;0044 DZ;01F1 DZcaron;01C4 Daarmenian;0534 Dafrican;0189 Dcaron;010E Dcedilla;1E10 Dcircle;24B9 Dcircumflexbelow;1E12 Dcroat;0110 Ddotaccent;1E0A Ddotbelow;1E0C Decyrillic;0414 Deicoptic;03EE Delta;2206 Deltagreek;0394 Dhook;018A Dieresis;F6CB DieresisAcute;F6CC DieresisGrave;F6CD Dieresissmall;F7A8 Digammagreek;03DC Djecyrillic;0402 Dlinebelow;1E0E Dmonospace;FF24 Dotaccentsmall;F6F7 Dslash;0110 Dsmall;F764 Dtopbar;018B Dz;01F2 Dzcaron;01C5 Dzeabkhasiancyrillic;04E0 Dzecyrillic;0405 Dzhecyrillic;040F E;0045 Eacute;00C9 Eacutesmall;F7E9 Ebreve;0114 Ecaron;011A Ecedillabreve;1E1C Echarmenian;0535 Ecircle;24BA Ecircumflex;00CA Ecircumflexacute;1EBE Ecircumflexbelow;1E18 Ecircumflexdotbelow;1EC6 Ecircumflexgrave;1EC0 Ecircumflexhookabove;1EC2 Ecircumflexsmall;F7EA Ecircumflextilde;1EC4 Ecyrillic;0404 Edblgrave;0204 Edieresis;00CB Edieresissmall;F7EB Edot;0116 Edotaccent;0116 Edotbelow;1EB8 Efcyrillic;0424 Egrave;00C8 Egravesmall;F7E8 Eharmenian;0537 Ehookabove;1EBA Eightroman;2167 Einvertedbreve;0206 Eiotifiedcyrillic;0464 Elcyrillic;041B Elevenroman;216A Emacron;0112 Emacronacute;1E16 Emacrongrave;1E14 Emcyrillic;041C Emonospace;FF25 Encyrillic;041D Endescendercyrillic;04A2 Eng;014A Enghecyrillic;04A4 Enhookcyrillic;04C7 Eogonek;0118 Eopen;0190 Epsilon;0395 Epsilontonos;0388 Ercyrillic;0420 Ereversed;018E Ereversedcyrillic;042D Escyrillic;0421 Esdescendercyrillic;04AA Esh;01A9 Esmall;F765 Eta;0397 Etarmenian;0538 Etatonos;0389 Eth;00D0 Ethsmall;F7F0 Etilde;1EBC Etildebelow;1E1A Euro;20AC Ezh;01B7 Ezhcaron;01EE Ezhreversed;01B8 F;0046 Fcircle;24BB Fdotaccent;1E1E Feharmenian;0556 Feicoptic;03E4 Fhook;0191 Fitacyrillic;0472 Fiveroman;2164 Fmonospace;FF26 Fourroman;2163 Fsmall;F766 G;0047 GBsquare;3387 Gacute;01F4 Gamma;0393 Gammaafrican;0194 Gangiacoptic;03EA Gbreve;011E Gcaron;01E6 Gcedilla;0122 Gcircle;24BC Gcircumflex;011C Gcommaaccent;0122 Gdot;0120 Gdotaccent;0120 Gecyrillic;0413 Ghadarmenian;0542 Ghemiddlehookcyrillic;0494 Ghestrokecyrillic;0492 Gheupturncyrillic;0490 Ghook;0193 Gimarmenian;0533 Gjecyrillic;0403 Gmacron;1E20 Gmonospace;FF27 Grave;F6CE Gravesmall;F760 Gsmall;F767 Gsmallhook;029B Gstroke;01E4 H;0048 H18533;25CF H18543;25AA H18551;25AB H22073;25A1 HPsquare;33CB Haabkhasiancyrillic;04A8 Hadescendercyrillic;04B2 Hardsigncyrillic;042A Hbar;0126 Hbrevebelow;1E2A Hcedilla;1E28 Hcircle;24BD Hcircumflex;0124 Hdieresis;1E26 Hdotaccent;1E22 Hdotbelow;1E24 Hmonospace;FF28 Hoarmenian;0540 Horicoptic;03E8 Hsmall;F768 Hungarumlaut;F6CF Hungarumlautsmall;F6F8 Hzsquare;3390 I;0049 IAcyrillic;042F IJ;0132 IUcyrillic;042E Iacute;00CD Iacutesmall;F7ED Ibreve;012C Icaron;01CF Icircle;24BE Icircumflex;00CE Icircumflexsmall;F7EE Icyrillic;0406 Idblgrave;0208 Idieresis;00CF Idieresisacute;1E2E Idieresiscyrillic;04E4 Idieresissmall;F7EF Idot;0130 Idotaccent;0130 Idotbelow;1ECA Iebrevecyrillic;04D6 Iecyrillic;0415 Ifraktur;2111 Igrave;00CC Igravesmall;F7EC Ihookabove;1EC8 Iicyrillic;0418 Iinvertedbreve;020A Iishortcyrillic;0419 Imacron;012A Imacroncyrillic;04E2 Imonospace;FF29 Iniarmenian;053B Iocyrillic;0401 Iogonek;012E Iota;0399 Iotaafrican;0196 Iotadieresis;03AA Iotatonos;038A Ismall;F769 Istroke;0197 Itilde;0128 Itildebelow;1E2C Izhitsacyrillic;0474 Izhitsadblgravecyrillic;0476 J;004A Jaarmenian;0541 Jcircle;24BF Jcircumflex;0134 Jecyrillic;0408 Jheharmenian;054B Jmonospace;FF2A Jsmall;F76A K;004B KBsquare;3385 KKsquare;33CD Kabashkircyrillic;04A0 Kacute;1E30 Kacyrillic;041A Kadescendercyrillic;049A Kahookcyrillic;04C3 Kappa;039A Kastrokecyrillic;049E Kaverticalstrokecyrillic;049C Kcaron;01E8 Kcedilla;0136 Kcircle;24C0 Kcommaaccent;0136 Kdotbelow;1E32 Keharmenian;0554 Kenarmenian;053F Khacyrillic;0425 Kheicoptic;03E6 Khook;0198 Kjecyrillic;040C Klinebelow;1E34 Kmonospace;FF2B Koppacyrillic;0480 Koppagreek;03DE Ksicyrillic;046E Ksmall;F76B L;004C LJ;01C7 LL;F6BF Lacute;0139 Lambda;039B Lcaron;013D Lcedilla;013B Lcircle;24C1 Lcircumflexbelow;1E3C Lcommaaccent;013B Ldot;013F Ldotaccent;013F Ldotbelow;1E36 Ldotbelowmacron;1E38 Liwnarmenian;053C Lj;01C8 Ljecyrillic;0409 Llinebelow;1E3A Lmonospace;FF2C Lslash;0141 Lslashsmall;F6F9 Lsmall;F76C M;004D MBsquare;3386 Macron;F6D0 Macronsmall;F7AF Macute;1E3E Mcircle;24C2 Mdotaccent;1E40 Mdotbelow;1E42 Menarmenian;0544 Mmonospace;FF2D Msmall;F76D Mturned;019C Mu;039C N;004E NJ;01CA Nacute;0143 Ncaron;0147 Ncedilla;0145 Ncircle;24C3 Ncircumflexbelow;1E4A Ncommaaccent;0145 Ndotaccent;1E44 Ndotbelow;1E46 Nhookleft;019D Nineroman;2168 Nj;01CB Njecyrillic;040A Nlinebelow;1E48 Nmonospace;FF2E Nowarmenian;0546 Nsmall;F76E Ntilde;00D1 Ntildesmall;F7F1 Nu;039D O;004F OE;0152 OEsmall;F6FA Oacute;00D3 Oacutesmall;F7F3 Obarredcyrillic;04E8 Obarreddieresiscyrillic;04EA Obreve;014E Ocaron;01D1 Ocenteredtilde;019F Ocircle;24C4 Ocircumflex;00D4 Ocircumflexacute;1ED0 Ocircumflexdotbelow;1ED8 Ocircumflexgrave;1ED2 Ocircumflexhookabove;1ED4 Ocircumflexsmall;F7F4 Ocircumflextilde;1ED6 Ocyrillic;041E Odblacute;0150 Odblgrave;020C Odieresis;00D6 Odieresiscyrillic;04E6 Odieresissmall;F7F6 Odotbelow;1ECC Ogoneksmall;F6FB Ograve;00D2 Ogravesmall;F7F2 Oharmenian;0555 Ohm;2126 Ohookabove;1ECE Ohorn;01A0 Ohornacute;1EDA Ohorndotbelow;1EE2 Ohorngrave;1EDC Ohornhookabove;1EDE Ohorntilde;1EE0 Ohungarumlaut;0150 Oi;01A2 Oinvertedbreve;020E Omacron;014C Omacronacute;1E52 Omacrongrave;1E50 Omega;2126 Omegacyrillic;0460 Omegagreek;03A9 Omegaroundcyrillic;047A Omegatitlocyrillic;047C Omegatonos;038F Omicron;039F Omicrontonos;038C Omonospace;FF2F Oneroman;2160 Oogonek;01EA Oogonekmacron;01EC Oopen;0186 Oslash;00D8 Oslashacute;01FE Oslashsmall;F7F8 Osmall;F76F Ostrokeacute;01FE Otcyrillic;047E Otilde;00D5 Otildeacute;1E4C Otildedieresis;1E4E Otildesmall;F7F5 P;0050 Pacute;1E54 Pcircle;24C5 Pdotaccent;1E56 Pecyrillic;041F Peharmenian;054A Pemiddlehookcyrillic;04A6 Phi;03A6 Phook;01A4 Pi;03A0 Piwrarmenian;0553 Pmonospace;FF30 Psi;03A8 Psicyrillic;0470 Psmall;F770 Q;0051 Qcircle;24C6 Qmonospace;FF31 Qsmall;F771 R;0052 Raarmenian;054C Racute;0154 Rcaron;0158 Rcedilla;0156 Rcircle;24C7 Rcommaaccent;0156 Rdblgrave;0210 Rdotaccent;1E58 Rdotbelow;1E5A Rdotbelowmacron;1E5C Reharmenian;0550 Rfraktur;211C Rho;03A1 Ringsmall;F6FC Rinvertedbreve;0212 Rlinebelow;1E5E Rmonospace;FF32 Rsmall;F772 Rsmallinverted;0281 Rsmallinvertedsuperior;02B6 S;0053 SF010000;250C SF020000;2514 SF030000;2510 SF040000;2518 SF050000;253C SF060000;252C SF070000;2534 SF080000;251C SF090000;2524 SF100000;2500 SF110000;2502 SF190000;2561 SF200000;2562 SF210000;2556 SF220000;2555 SF230000;2563 SF240000;2551 SF250000;2557 SF260000;255D SF270000;255C SF280000;255B SF360000;255E SF370000;255F SF380000;255A SF390000;2554 SF400000;2569 SF410000;2566 SF420000;2560 SF430000;2550 SF440000;256C SF450000;2567 SF460000;2568 SF470000;2564 SF480000;2565 SF490000;2559 SF500000;2558 SF510000;2552 SF520000;2553 SF530000;256B SF540000;256A Sacute;015A Sacutedotaccent;1E64 Sampigreek;03E0 Scaron;0160 Scarondotaccent;1E66 Scaronsmall;F6FD Scedilla;015E Schwa;018F Schwacyrillic;04D8 Schwadieresiscyrillic;04DA Scircle;24C8 Scircumflex;015C Scommaaccent;0218 Sdotaccent;1E60 Sdotbelow;1E62 Sdotbelowdotaccent;1E68 Seharmenian;054D Sevenroman;2166 Shaarmenian;0547 Shacyrillic;0428 Shchacyrillic;0429 Sheicoptic;03E2 Shhacyrillic;04BA Shimacoptic;03EC Sigma;03A3 Sixroman;2165 Smonospace;FF33 Softsigncyrillic;042C Ssmall;F773 Stigmagreek;03DA T;0054 Tau;03A4 Tbar;0166 Tcaron;0164 Tcedilla;0162 Tcircle;24C9 Tcircumflexbelow;1E70 Tcommaaccent;0162 Tdotaccent;1E6A Tdotbelow;1E6C Tecyrillic;0422 Tedescendercyrillic;04AC Tenroman;2169 Tetsecyrillic;04B4 Theta;0398 Thook;01AC Thorn;00DE Thornsmall;F7FE Threeroman;2162 Tildesmall;F6FE Tiwnarmenian;054F Tlinebelow;1E6E Tmonospace;FF34 Toarmenian;0539 Tonefive;01BC Tonesix;0184 Tonetwo;01A7 Tretroflexhook;01AE Tsecyrillic;0426 Tshecyrillic;040B Tsmall;F774 Twelveroman;216B Tworoman;2161 U;0055 Uacute;00DA Uacutesmall;F7FA Ubreve;016C Ucaron;01D3 Ucircle;24CA Ucircumflex;00DB Ucircumflexbelow;1E76 Ucircumflexsmall;F7FB Ucyrillic;0423 Udblacute;0170 Udblgrave;0214 Udieresis;00DC Udieresisacute;01D7 Udieresisbelow;1E72 Udieresiscaron;01D9 Udieresiscyrillic;04F0 Udieresisgrave;01DB Udieresismacron;01D5 Udieresissmall;F7FC Udotbelow;1EE4 Ugrave;00D9 Ugravesmall;F7F9 Uhookabove;1EE6 Uhorn;01AF Uhornacute;1EE8 Uhorndotbelow;1EF0 Uhorngrave;1EEA Uhornhookabove;1EEC Uhorntilde;1EEE Uhungarumlaut;0170 Uhungarumlautcyrillic;04F2 Uinvertedbreve;0216 Ukcyrillic;0478 Umacron;016A Umacroncyrillic;04EE Umacrondieresis;1E7A Umonospace;FF35 Uogonek;0172 Upsilon;03A5 Upsilon1;03D2 Upsilonacutehooksymbolgreek;03D3 Upsilonafrican;01B1 Upsilondieresis;03AB Upsilondieresishooksymbolgreek;03D4 Upsilonhooksymbol;03D2 Upsilontonos;038E Uring;016E Ushortcyrillic;040E Usmall;F775 Ustraightcyrillic;04AE Ustraightstrokecyrillic;04B0 Utilde;0168 Utildeacute;1E78 Utildebelow;1E74 V;0056 Vcircle;24CB Vdotbelow;1E7E Vecyrillic;0412 Vewarmenian;054E Vhook;01B2 Vmonospace;FF36 Voarmenian;0548 Vsmall;F776 Vtilde;1E7C W;0057 Wacute;1E82 Wcircle;24CC Wcircumflex;0174 Wdieresis;1E84 Wdotaccent;1E86 Wdotbelow;1E88 Wgrave;1E80 Wmonospace;FF37 Wsmall;F777 X;0058 Xcircle;24CD Xdieresis;1E8C Xdotaccent;1E8A Xeharmenian;053D Xi;039E Xmonospace;FF38 Xsmall;F778 Y;0059 Yacute;00DD Yacutesmall;F7FD Yatcyrillic;0462 Ycircle;24CE Ycircumflex;0176 Ydieresis;0178 Ydieresissmall;F7FF Ydotaccent;1E8E Ydotbelow;1EF4 Yericyrillic;042B Yerudieresiscyrillic;04F8 Ygrave;1EF2 Yhook;01B3 Yhookabove;1EF6 Yiarmenian;0545 Yicyrillic;0407 Yiwnarmenian;0552 Ymonospace;FF39 Ysmall;F779 Ytilde;1EF8 Yusbigcyrillic;046A Yusbigiotifiedcyrillic;046C Yuslittlecyrillic;0466 Yuslittleiotifiedcyrillic;0468 Z;005A Zaarmenian;0536 Zacute;0179 Zcaron;017D Zcaronsmall;F6FF Zcircle;24CF Zcircumflex;1E90 Zdot;017B Zdotaccent;017B Zdotbelow;1E92 Zecyrillic;0417 Zedescendercyrillic;0498 Zedieresiscyrillic;04DE Zeta;0396 Zhearmenian;053A Zhebrevecyrillic;04C1 Zhecyrillic;0416 Zhedescendercyrillic;0496 Zhedieresiscyrillic;04DC Zlinebelow;1E94 Zmonospace;FF3A Zsmall;F77A Zstroke;01B5 a;0061 aabengali;0986 aacute;00E1 aadeva;0906 aagujarati;0A86 aagurmukhi;0A06 aamatragurmukhi;0A3E aarusquare;3303 aavowelsignbengali;09BE aavowelsigndeva;093E aavowelsigngujarati;0ABE abbreviationmarkarmenian;055F abbreviationsigndeva;0970 abengali;0985 abopomofo;311A abreve;0103 abreveacute;1EAF abrevecyrillic;04D1 abrevedotbelow;1EB7 abrevegrave;1EB1 abrevehookabove;1EB3 abrevetilde;1EB5 acaron;01CE acircle;24D0 acircumflex;00E2 acircumflexacute;1EA5 acircumflexdotbelow;1EAD acircumflexgrave;1EA7 acircumflexhookabove;1EA9 acircumflextilde;1EAB acute;00B4 acutebelowcmb;0317 acutecmb;0301 acutecomb;0301 acutedeva;0954 acutelowmod;02CF acutetonecmb;0341 acyrillic;0430 adblgrave;0201 addakgurmukhi;0A71 adeva;0905 adieresis;00E4 adieresiscyrillic;04D3 adieresismacron;01DF adotbelow;1EA1 adotmacron;01E1 ae;00E6 aeacute;01FD aekorean;3150 aemacron;01E3 afii00208;2015 afii08941;20A4 afii10017;0410 afii10018;0411 afii10019;0412 afii10020;0413 afii10021;0414 afii10022;0415 afii10023;0401 afii10024;0416 afii10025;0417 afii10026;0418 afii10027;0419 afii10028;041A afii10029;041B afii10030;041C afii10031;041D afii10032;041E afii10033;041F afii10034;0420 afii10035;0421 afii10036;0422 afii10037;0423 afii10038;0424 afii10039;0425 afii10040;0426 afii10041;0427 afii10042;0428 afii10043;0429 afii10044;042A afii10045;042B afii10046;042C afii10047;042D afii10048;042E afii10049;042F afii10050;0490 afii10051;0402 afii10052;0403 afii10053;0404 afii10054;0405 afii10055;0406 afii10056;0407 afii10057;0408 afii10058;0409 afii10059;040A afii10060;040B afii10061;040C afii10062;040E afii10063;F6C4 afii10064;F6C5 afii10065;0430 afii10066;0431 afii10067;0432 afii10068;0433 afii10069;0434 afii10070;0435 afii10071;0451 afii10072;0436 afii10073;0437 afii10074;0438 afii10075;0439 afii10076;043A afii10077;043B afii10078;043C afii10079;043D afii10080;043E afii10081;043F afii10082;0440 afii10083;0441 afii10084;0442 afii10085;0443 afii10086;0444 afii10087;0445 afii10088;0446 afii10089;0447 afii10090;0448 afii10091;0449 afii10092;044A afii10093;044B afii10094;044C afii10095;044D afii10096;044E afii10097;044F afii10098;0491 afii10099;0452 afii10100;0453 afii10101;0454 afii10102;0455 afii10103;0456 afii10104;0457 afii10105;0458 afii10106;0459 afii10107;045A afii10108;045B afii10109;045C afii10110;045E afii10145;040F afii10146;0462 afii10147;0472 afii10148;0474 afii10192;F6C6 afii10193;045F afii10194;0463 afii10195;0473 afii10196;0475 afii10831;F6C7 afii10832;F6C8 afii10846;04D9 afii299;200E afii300;200F afii301;200D afii57381;066A afii57388;060C afii57392;0660 afii57393;0661 afii57394;0662 afii57395;0663 afii57396;0664 afii57397;0665 afii57398;0666 afii57399;0667 afii57400;0668 afii57401;0669 afii57403;061B afii57407;061F afii57409;0621 afii57410;0622 afii57411;0623 afii57412;0624 afii57413;0625 afii57414;0626 afii57415;0627 afii57416;0628 afii57417;0629 afii57418;062A afii57419;062B afii57420;062C afii57421;062D afii57422;062E afii57423;062F afii57424;0630 afii57425;0631 afii57426;0632 afii57427;0633 afii57428;0634 afii57429;0635 afii57430;0636 afii57431;0637 afii57432;0638 afii57433;0639 afii57434;063A afii57440;0640 afii57441;0641 afii57442;0642 afii57443;0643 afii57444;0644 afii57445;0645 afii57446;0646 afii57448;0648 afii57449;0649 afii57450;064A afii57451;064B afii57452;064C afii57453;064D afii57454;064E afii57455;064F afii57456;0650 afii57457;0651 afii57458;0652 afii57470;0647 afii57505;06A4 afii57506;067E afii57507;0686 afii57508;0698 afii57509;06AF afii57511;0679 afii57512;0688 afii57513;0691 afii57514;06BA afii57519;06D2 afii57534;06D5 afii57636;20AA afii57645;05BE afii57658;05C3 afii57664;05D0 afii57665;05D1 afii57666;05D2 afii57667;05D3 afii57668;05D4 afii57669;05D5 afii57670;05D6 afii57671;05D7 afii57672;05D8 afii57673;05D9 afii57674;05DA afii57675;05DB afii57676;05DC afii57677;05DD afii57678;05DE afii57679;05DF afii57680;05E0 afii57681;05E1 afii57682;05E2 afii57683;05E3 afii57684;05E4 afii57685;05E5 afii57686;05E6 afii57687;05E7 afii57688;05E8 afii57689;05E9 afii57690;05EA afii57694;FB2A afii57695;FB2B afii57700;FB4B afii57705;FB1F afii57716;05F0 afii57717;05F1 afii57718;05F2 afii57723;FB35 afii57793;05B4 afii57794;05B5 afii57795;05B6 afii57796;05BB afii57797;05B8 afii57798;05B7 afii57799;05B0 afii57800;05B2 afii57801;05B1 afii57802;05B3 afii57803;05C2 afii57804;05C1 afii57806;05B9 afii57807;05BC afii57839;05BD afii57841;05BF afii57842;05C0 afii57929;02BC afii61248;2105 afii61289;2113 afii61352;2116 afii61573;202C afii61574;202D afii61575;202E afii61664;200C afii63167;066D afii64937;02BD agrave;00E0 agujarati;0A85 agurmukhi;0A05 ahiragana;3042 ahookabove;1EA3 aibengali;0990 aibopomofo;311E aideva;0910 aiecyrillic;04D5 aigujarati;0A90 aigurmukhi;0A10 aimatragurmukhi;0A48 ainarabic;0639 ainfinalarabic;FECA aininitialarabic;FECB ainmedialarabic;FECC ainvertedbreve;0203 aivowelsignbengali;09C8 aivowelsigndeva;0948 aivowelsigngujarati;0AC8 akatakana;30A2 akatakanahalfwidth;FF71 akorean;314F alef;05D0 alefarabic;0627 alefdageshhebrew;FB30 aleffinalarabic;FE8E alefhamzaabovearabic;0623 alefhamzaabovefinalarabic;FE84 alefhamzabelowarabic;0625 alefhamzabelowfinalarabic;FE88 alefhebrew;05D0 aleflamedhebrew;FB4F alefmaddaabovearabic;0622 alefmaddaabovefinalarabic;FE82 alefmaksuraarabic;0649 alefmaksurafinalarabic;FEF0 alefmaksurainitialarabic;FEF3 alefmaksuramedialarabic;FEF4 alefpatahhebrew;FB2E alefqamatshebrew;FB2F aleph;2135 allequal;224C alpha;03B1 alphatonos;03AC amacron;0101 amonospace;FF41 ampersand;0026 ampersandmonospace;FF06 ampersandsmall;F726 amsquare;33C2 anbopomofo;3122 angbopomofo;3124 angkhankhuthai;0E5A angle;2220 anglebracketleft;3008 anglebracketleftvertical;FE3F anglebracketright;3009 anglebracketrightvertical;FE40 angleleft;2329 angleright;232A angstrom;212B anoteleia;0387 anudattadeva;0952 anusvarabengali;0982 anusvaradeva;0902 anusvaragujarati;0A82 aogonek;0105 apaatosquare;3300 aparen;249C apostrophearmenian;055A apostrophemod;02BC apple;F8FF approaches;2250 approxequal;2248 approxequalorimage;2252 approximatelyequal;2245 araeaekorean;318E araeakorean;318D arc;2312 arighthalfring;1E9A aring;00E5 aringacute;01FB aringbelow;1E01 arrowboth;2194 arrowdashdown;21E3 arrowdashleft;21E0 arrowdashright;21E2 arrowdashup;21E1 arrowdblboth;21D4 arrowdbldown;21D3 arrowdblleft;21D0 arrowdblright;21D2 arrowdblup;21D1 arrowdown;2193 arrowdownleft;2199 arrowdownright;2198 arrowdownwhite;21E9 arrowheaddownmod;02C5 arrowheadleftmod;02C2 arrowheadrightmod;02C3 arrowheadupmod;02C4 arrowhorizex;F8E7 arrowleft;2190 arrowleftdbl;21D0 arrowleftdblstroke;21CD arrowleftoverright;21C6 arrowleftwhite;21E6 arrowright;2192 arrowrightdblstroke;21CF arrowrightheavy;279E arrowrightoverleft;21C4 arrowrightwhite;21E8 arrowtableft;21E4 arrowtabright;21E5 arrowup;2191 arrowupdn;2195 arrowupdnbse;21A8 arrowupdownbase;21A8 arrowupleft;2196 arrowupleftofdown;21C5 arrowupright;2197 arrowupwhite;21E7 arrowvertex;F8E6 asciicircum;005E asciicircummonospace;FF3E asciitilde;007E asciitildemonospace;FF5E ascript;0251 ascriptturned;0252 asmallhiragana;3041 asmallkatakana;30A1 asmallkatakanahalfwidth;FF67 asterisk;002A asteriskaltonearabic;066D asteriskarabic;066D asteriskmath;2217 asteriskmonospace;FF0A asterisksmall;FE61 asterism;2042 asuperior;F6E9 asymptoticallyequal;2243 at;0040 atilde;00E3 atmonospace;FF20 atsmall;FE6B aturned;0250 aubengali;0994 aubopomofo;3120 audeva;0914 augujarati;0A94 augurmukhi;0A14 aulengthmarkbengali;09D7 aumatragurmukhi;0A4C auvowelsignbengali;09CC auvowelsigndeva;094C auvowelsigngujarati;0ACC avagrahadeva;093D aybarmenian;0561 ayin;05E2 ayinaltonehebrew;FB20 ayinhebrew;05E2 b;0062 babengali;09AC backslash;005C backslashmonospace;FF3C badeva;092C bagujarati;0AAC bagurmukhi;0A2C bahiragana;3070 bahtthai;0E3F bakatakana;30D0 bar;007C barmonospace;FF5C bbopomofo;3105 bcircle;24D1 bdotaccent;1E03 bdotbelow;1E05 beamedsixteenthnotes;266C because;2235 becyrillic;0431 beharabic;0628 behfinalarabic;FE90 behinitialarabic;FE91 behiragana;3079 behmedialarabic;FE92 behmeeminitialarabic;FC9F behmeemisolatedarabic;FC08 behnoonfinalarabic;FC6D bekatakana;30D9 benarmenian;0562 bet;05D1 beta;03B2 betasymbolgreek;03D0 betdagesh;FB31 betdageshhebrew;FB31 bethebrew;05D1 betrafehebrew;FB4C bhabengali;09AD bhadeva;092D bhagujarati;0AAD bhagurmukhi;0A2D bhook;0253 bihiragana;3073 bikatakana;30D3 bilabialclick;0298 bindigurmukhi;0A02 birusquare;3331 blackcircle;25CF blackdiamond;25C6 blackdownpointingtriangle;25BC blackleftpointingpointer;25C4 blackleftpointingtriangle;25C0 blacklenticularbracketleft;3010 blacklenticularbracketleftvertical;FE3B blacklenticularbracketright;3011 blacklenticularbracketrightvertical;FE3C blacklowerlefttriangle;25E3 blacklowerrighttriangle;25E2 blackrectangle;25AC blackrightpointingpointer;25BA blackrightpointingtriangle;25B6 blacksmallsquare;25AA blacksmilingface;263B blacksquare;25A0 blackstar;2605 blackupperlefttriangle;25E4 blackupperrighttriangle;25E5 blackuppointingsmalltriangle;25B4 blackuppointingtriangle;25B2 blank;2423 blinebelow;1E07 block;2588 bmonospace;FF42 bobaimaithai;0E1A bohiragana;307C bokatakana;30DC bparen;249D bqsquare;33C3 braceex;F8F4 braceleft;007B braceleftbt;F8F3 braceleftmid;F8F2 braceleftmonospace;FF5B braceleftsmall;FE5B bracelefttp;F8F1 braceleftvertical;FE37 braceright;007D bracerightbt;F8FE bracerightmid;F8FD bracerightmonospace;FF5D bracerightsmall;FE5C bracerighttp;F8FC bracerightvertical;FE38 bracketleft;005B bracketleftbt;F8F0 bracketleftex;F8EF bracketleftmonospace;FF3B bracketlefttp;F8EE bracketright;005D bracketrightbt;F8FB bracketrightex;F8FA bracketrightmonospace;FF3D bracketrighttp;F8F9 breve;02D8 brevebelowcmb;032E brevecmb;0306 breveinvertedbelowcmb;032F breveinvertedcmb;0311 breveinverteddoublecmb;0361 bridgebelowcmb;032A bridgeinvertedbelowcmb;033A brokenbar;00A6 bstroke;0180 bsuperior;F6EA btopbar;0183 buhiragana;3076 bukatakana;30D6 bullet;2022 bulletinverse;25D8 bulletoperator;2219 bullseye;25CE c;0063 caarmenian;056E cabengali;099A cacute;0107 cadeva;091A cagujarati;0A9A cagurmukhi;0A1A calsquare;3388 candrabindubengali;0981 candrabinducmb;0310 candrabindudeva;0901 candrabindugujarati;0A81 capslock;21EA careof;2105 caron;02C7 caronbelowcmb;032C caroncmb;030C carriagereturn;21B5 cbopomofo;3118 ccaron;010D ccedilla;00E7 ccedillaacute;1E09 ccircle;24D2 ccircumflex;0109 ccurl;0255 cdot;010B cdotaccent;010B cdsquare;33C5 cedilla;00B8 cedillacmb;0327 cent;00A2 centigrade;2103 centinferior;F6DF centmonospace;FFE0 centoldstyle;F7A2 centsuperior;F6E0 chaarmenian;0579 chabengali;099B chadeva;091B chagujarati;0A9B chagurmukhi;0A1B chbopomofo;3114 cheabkhasiancyrillic;04BD checkmark;2713 checyrillic;0447 chedescenderabkhasiancyrillic;04BF chedescendercyrillic;04B7 chedieresiscyrillic;04F5 cheharmenian;0573 chekhakassiancyrillic;04CC cheverticalstrokecyrillic;04B9 chi;03C7 chieuchacirclekorean;3277 chieuchaparenkorean;3217 chieuchcirclekorean;3269 chieuchkorean;314A chieuchparenkorean;3209 chochangthai;0E0A chochanthai;0E08 chochingthai;0E09 chochoethai;0E0C chook;0188 cieucacirclekorean;3276 cieucaparenkorean;3216 cieuccirclekorean;3268 cieuckorean;3148 cieucparenkorean;3208 cieucuparenkorean;321C circle;25CB circlemultiply;2297 circleot;2299 circleplus;2295 circlepostalmark;3036 circlewithlefthalfblack;25D0 circlewithrighthalfblack;25D1 circumflex;02C6 circumflexbelowcmb;032D circumflexcmb;0302 clear;2327 clickalveolar;01C2 clickdental;01C0 clicklateral;01C1 clickretroflex;01C3 club;2663 clubsuitblack;2663 clubsuitwhite;2667 cmcubedsquare;33A4 cmonospace;FF43 cmsquaredsquare;33A0 coarmenian;0581 colon;003A colonmonetary;20A1 colonmonospace;FF1A colonsign;20A1 colonsmall;FE55 colontriangularhalfmod;02D1 colontriangularmod;02D0 comma;002C commaabovecmb;0313 commaaboverightcmb;0315 commaaccent;F6C3 commaarabic;060C commaarmenian;055D commainferior;F6E1 commamonospace;FF0C commareversedabovecmb;0314 commareversedmod;02BD commasmall;FE50 commasuperior;F6E2 commaturnedabovecmb;0312 commaturnedmod;02BB compass;263C congruent;2245 contourintegral;222E control;2303 controlACK;0006 controlBEL;0007 controlBS;0008 controlCAN;0018 controlCR;000D controlDC1;0011 controlDC2;0012 controlDC3;0013 controlDC4;0014 controlDEL;007F controlDLE;0010 controlEM;0019 controlENQ;0005 controlEOT;0004 controlESC;001B controlETB;0017 controlETX;0003 controlFF;000C controlFS;001C controlGS;001D controlHT;0009 controlLF;000A controlNAK;0015 controlRS;001E controlSI;000F controlSO;000E controlSOT;0002 controlSTX;0001 controlSUB;001A controlSYN;0016 controlUS;001F controlVT;000B copyright;00A9 copyrightsans;F8E9 copyrightserif;F6D9 cornerbracketleft;300C cornerbracketlefthalfwidth;FF62 cornerbracketleftvertical;FE41 cornerbracketright;300D cornerbracketrighthalfwidth;FF63 cornerbracketrightvertical;FE42 corporationsquare;337F cosquare;33C7 coverkgsquare;33C6 cparen;249E cruzeiro;20A2 cstretched;0297 curlyand;22CF curlyor;22CE currency;00A4 cyrBreve;F6D1 cyrFlex;F6D2 cyrbreve;F6D4 cyrflex;F6D5 d;0064 daarmenian;0564 dabengali;09A6 dadarabic;0636 dadeva;0926 dadfinalarabic;FEBE dadinitialarabic;FEBF dadmedialarabic;FEC0 dagesh;05BC dageshhebrew;05BC dagger;2020 daggerdbl;2021 dagujarati;0AA6 dagurmukhi;0A26 dahiragana;3060 dakatakana;30C0 dalarabic;062F dalet;05D3 daletdagesh;FB33 daletdageshhebrew;FB33 dalethatafpatah;05D3 05B2 dalethatafpatahhebrew;05D3 05B2 dalethatafsegol;05D3 05B1 dalethatafsegolhebrew;05D3 05B1 dalethebrew;05D3 dalethiriq;05D3 05B4 dalethiriqhebrew;05D3 05B4 daletholam;05D3 05B9 daletholamhebrew;05D3 05B9 daletpatah;05D3 05B7 daletpatahhebrew;05D3 05B7 daletqamats;05D3 05B8 daletqamatshebrew;05D3 05B8 daletqubuts;05D3 05BB daletqubutshebrew;05D3 05BB daletsegol;05D3 05B6 daletsegolhebrew;05D3 05B6 daletsheva;05D3 05B0 daletshevahebrew;05D3 05B0 dalettsere;05D3 05B5 dalettserehebrew;05D3 05B5 dalfinalarabic;FEAA dammaarabic;064F dammalowarabic;064F dammatanaltonearabic;064C dammatanarabic;064C danda;0964 dargahebrew;05A7 dargalefthebrew;05A7 dasiapneumatacyrilliccmb;0485 dblGrave;F6D3 dblanglebracketleft;300A dblanglebracketleftvertical;FE3D dblanglebracketright;300B dblanglebracketrightvertical;FE3E dblarchinvertedbelowcmb;032B dblarrowleft;21D4 dblarrowright;21D2 dbldanda;0965 dblgrave;F6D6 dblgravecmb;030F dblintegral;222C dbllowline;2017 dbllowlinecmb;0333 dbloverlinecmb;033F dblprimemod;02BA dblverticalbar;2016 dblverticallineabovecmb;030E dbopomofo;3109 dbsquare;33C8 dcaron;010F dcedilla;1E11 dcircle;24D3 dcircumflexbelow;1E13 dcroat;0111 ddabengali;09A1 ddadeva;0921 ddagujarati;0AA1 ddagurmukhi;0A21 ddalarabic;0688 ddalfinalarabic;FB89 dddhadeva;095C ddhabengali;09A2 ddhadeva;0922 ddhagujarati;0AA2 ddhagurmukhi;0A22 ddotaccent;1E0B ddotbelow;1E0D decimalseparatorarabic;066B decimalseparatorpersian;066B decyrillic;0434 degree;00B0 dehihebrew;05AD dehiragana;3067 deicoptic;03EF dekatakana;30C7 deleteleft;232B deleteright;2326 delta;03B4 deltaturned;018D denominatorminusonenumeratorbengali;09F8 dezh;02A4 dhabengali;09A7 dhadeva;0927 dhagujarati;0AA7 dhagurmukhi;0A27 dhook;0257 dialytikatonos;0385 dialytikatonoscmb;0344 diamond;2666 diamondsuitwhite;2662 dieresis;00A8 dieresisacute;F6D7 dieresisbelowcmb;0324 dieresiscmb;0308 dieresisgrave;F6D8 dieresistonos;0385 dihiragana;3062 dikatakana;30C2 dittomark;3003 divide;00F7 divides;2223 divisionslash;2215 djecyrillic;0452 dkshade;2593 dlinebelow;1E0F dlsquare;3397 dmacron;0111 dmonospace;FF44 dnblock;2584 dochadathai;0E0E dodekthai;0E14 dohiragana;3069 dokatakana;30C9 dollar;0024 dollarinferior;F6E3 dollarmonospace;FF04 dollaroldstyle;F724 dollarsmall;FE69 dollarsuperior;F6E4 dong;20AB dorusquare;3326 dotaccent;02D9 dotaccentcmb;0307 dotbelowcmb;0323 dotbelowcomb;0323 dotkatakana;30FB dotlessi;0131 dotlessj;F6BE dotlessjstrokehook;0284 dotmath;22C5 dottedcircle;25CC doubleyodpatah;FB1F doubleyodpatahhebrew;FB1F downtackbelowcmb;031E downtackmod;02D5 dparen;249F dsuperior;F6EB dtail;0256 dtopbar;018C duhiragana;3065 dukatakana;30C5 dz;01F3 dzaltone;02A3 dzcaron;01C6 dzcurl;02A5 dzeabkhasiancyrillic;04E1 dzecyrillic;0455 dzhecyrillic;045F e;0065 eacute;00E9 earth;2641 ebengali;098F ebopomofo;311C ebreve;0115 ecandradeva;090D ecandragujarati;0A8D ecandravowelsigndeva;0945 ecandravowelsigngujarati;0AC5 ecaron;011B ecedillabreve;1E1D echarmenian;0565 echyiwnarmenian;0587 ecircle;24D4 ecircumflex;00EA ecircumflexacute;1EBF ecircumflexbelow;1E19 ecircumflexdotbelow;1EC7 ecircumflexgrave;1EC1 ecircumflexhookabove;1EC3 ecircumflextilde;1EC5 ecyrillic;0454 edblgrave;0205 edeva;090F edieresis;00EB edot;0117 edotaccent;0117 edotbelow;1EB9 eegurmukhi;0A0F eematragurmukhi;0A47 efcyrillic;0444 egrave;00E8 egujarati;0A8F eharmenian;0567 ehbopomofo;311D ehiragana;3048 ehookabove;1EBB eibopomofo;311F eight;0038 eightarabic;0668 eightbengali;09EE eightcircle;2467 eightcircleinversesansserif;2791 eightdeva;096E eighteencircle;2471 eighteenparen;2485 eighteenperiod;2499 eightgujarati;0AEE eightgurmukhi;0A6E eighthackarabic;0668 eighthangzhou;3028 eighthnotebeamed;266B eightideographicparen;3227 eightinferior;2088 eightmonospace;FF18 eightoldstyle;F738 eightparen;247B eightperiod;248F eightpersian;06F8 eightroman;2177 eightsuperior;2078 eightthai;0E58 einvertedbreve;0207 eiotifiedcyrillic;0465 ekatakana;30A8 ekatakanahalfwidth;FF74 ekonkargurmukhi;0A74 ekorean;3154 elcyrillic;043B element;2208 elevencircle;246A elevenparen;247E elevenperiod;2492 elevenroman;217A ellipsis;2026 ellipsisvertical;22EE emacron;0113 emacronacute;1E17 emacrongrave;1E15 emcyrillic;043C emdash;2014 emdashvertical;FE31 emonospace;FF45 emphasismarkarmenian;055B emptyset;2205 enbopomofo;3123 encyrillic;043D endash;2013 endashvertical;FE32 endescendercyrillic;04A3 eng;014B engbopomofo;3125 enghecyrillic;04A5 enhookcyrillic;04C8 enspace;2002 eogonek;0119 eokorean;3153 eopen;025B eopenclosed;029A eopenreversed;025C eopenreversedclosed;025E eopenreversedhook;025D eparen;24A0 epsilon;03B5 epsilontonos;03AD equal;003D equalmonospace;FF1D equalsmall;FE66 equalsuperior;207C equivalence;2261 erbopomofo;3126 ercyrillic;0440 ereversed;0258 ereversedcyrillic;044D escyrillic;0441 esdescendercyrillic;04AB esh;0283 eshcurl;0286 eshortdeva;090E eshortvowelsigndeva;0946 eshreversedloop;01AA eshsquatreversed;0285 esmallhiragana;3047 esmallkatakana;30A7 esmallkatakanahalfwidth;FF6A estimated;212E esuperior;F6EC eta;03B7 etarmenian;0568 etatonos;03AE eth;00F0 etilde;1EBD etildebelow;1E1B etnahtafoukhhebrew;0591 etnahtafoukhlefthebrew;0591 etnahtahebrew;0591 etnahtalefthebrew;0591 eturned;01DD eukorean;3161 euro;20AC evowelsignbengali;09C7 evowelsigndeva;0947 evowelsigngujarati;0AC7 exclam;0021 exclamarmenian;055C exclamdbl;203C exclamdown;00A1 exclamdownsmall;F7A1 exclammonospace;FF01 exclamsmall;F721 existential;2203 ezh;0292 ezhcaron;01EF ezhcurl;0293 ezhreversed;01B9 ezhtail;01BA f;0066 fadeva;095E fagurmukhi;0A5E fahrenheit;2109 fathaarabic;064E fathalowarabic;064E fathatanarabic;064B fbopomofo;3108 fcircle;24D5 fdotaccent;1E1F feharabic;0641 feharmenian;0586 fehfinalarabic;FED2 fehinitialarabic;FED3 fehmedialarabic;FED4 feicoptic;03E5 female;2640 ff;FB00 ffi;FB03 ffl;FB04 fi;FB01 fifteencircle;246E fifteenparen;2482 fifteenperiod;2496 figuredash;2012 filledbox;25A0 filledrect;25AC finalkaf;05DA finalkafdagesh;FB3A finalkafdageshhebrew;FB3A finalkafhebrew;05DA finalkafqamats;05DA 05B8 finalkafqamatshebrew;05DA 05B8 finalkafsheva;05DA 05B0 finalkafshevahebrew;05DA 05B0 finalmem;05DD finalmemhebrew;05DD finalnun;05DF finalnunhebrew;05DF finalpe;05E3 finalpehebrew;05E3 finaltsadi;05E5 finaltsadihebrew;05E5 firsttonechinese;02C9 fisheye;25C9 fitacyrillic;0473 five;0035 fivearabic;0665 fivebengali;09EB fivecircle;2464 fivecircleinversesansserif;278E fivedeva;096B fiveeighths;215D fivegujarati;0AEB fivegurmukhi;0A6B fivehackarabic;0665 fivehangzhou;3025 fiveideographicparen;3224 fiveinferior;2085 fivemonospace;FF15 fiveoldstyle;F735 fiveparen;2478 fiveperiod;248C fivepersian;06F5 fiveroman;2174 fivesuperior;2075 fivethai;0E55 fl;FB02 florin;0192 fmonospace;FF46 fmsquare;3399 fofanthai;0E1F fofathai;0E1D fongmanthai;0E4F forall;2200 four;0034 fourarabic;0664 fourbengali;09EA fourcircle;2463 fourcircleinversesansserif;278D fourdeva;096A fourgujarati;0AEA fourgurmukhi;0A6A fourhackarabic;0664 fourhangzhou;3024 fourideographicparen;3223 fourinferior;2084 fourmonospace;FF14 fournumeratorbengali;09F7 fouroldstyle;F734 fourparen;2477 fourperiod;248B fourpersian;06F4 fourroman;2173 foursuperior;2074 fourteencircle;246D fourteenparen;2481 fourteenperiod;2495 fourthai;0E54 fourthtonechinese;02CB fparen;24A1 fraction;2044 franc;20A3 g;0067 gabengali;0997 gacute;01F5 gadeva;0917 gafarabic;06AF gaffinalarabic;FB93 gafinitialarabic;FB94 gafmedialarabic;FB95 gagujarati;0A97 gagurmukhi;0A17 gahiragana;304C gakatakana;30AC gamma;03B3 gammalatinsmall;0263 gammasuperior;02E0 gangiacoptic;03EB gbopomofo;310D gbreve;011F gcaron;01E7 gcedilla;0123 gcircle;24D6 gcircumflex;011D gcommaaccent;0123 gdot;0121 gdotaccent;0121 gecyrillic;0433 gehiragana;3052 gekatakana;30B2 geometricallyequal;2251 gereshaccenthebrew;059C gereshhebrew;05F3 gereshmuqdamhebrew;059D germandbls;00DF gershayimaccenthebrew;059E gershayimhebrew;05F4 getamark;3013 ghabengali;0998 ghadarmenian;0572 ghadeva;0918 ghagujarati;0A98 ghagurmukhi;0A18 ghainarabic;063A ghainfinalarabic;FECE ghaininitialarabic;FECF ghainmedialarabic;FED0 ghemiddlehookcyrillic;0495 ghestrokecyrillic;0493 gheupturncyrillic;0491 ghhadeva;095A ghhagurmukhi;0A5A ghook;0260 ghzsquare;3393 gihiragana;304E gikatakana;30AE gimarmenian;0563 gimel;05D2 gimeldagesh;FB32 gimeldageshhebrew;FB32 gimelhebrew;05D2 gjecyrillic;0453 glottalinvertedstroke;01BE glottalstop;0294 glottalstopinverted;0296 glottalstopmod;02C0 glottalstopreversed;0295 glottalstopreversedmod;02C1 glottalstopreversedsuperior;02E4 glottalstopstroke;02A1 glottalstopstrokereversed;02A2 gmacron;1E21 gmonospace;FF47 gohiragana;3054 gokatakana;30B4 gparen;24A2 gpasquare;33AC gradient;2207 grave;0060 gravebelowcmb;0316 gravecmb;0300 gravecomb;0300 gravedeva;0953 gravelowmod;02CE gravemonospace;FF40 gravetonecmb;0340 greater;003E greaterequal;2265 greaterequalorless;22DB greatermonospace;FF1E greaterorequivalent;2273 greaterorless;2277 greateroverequal;2267 greatersmall;FE65 gscript;0261 gstroke;01E5 guhiragana;3050 guillemotleft;00AB guillemotright;00BB guilsinglleft;2039 guilsinglright;203A gukatakana;30B0 guramusquare;3318 gysquare;33C9 h;0068 haabkhasiancyrillic;04A9 haaltonearabic;06C1 habengali;09B9 hadescendercyrillic;04B3 hadeva;0939 hagujarati;0AB9 hagurmukhi;0A39 haharabic;062D hahfinalarabic;FEA2 hahinitialarabic;FEA3 hahiragana;306F hahmedialarabic;FEA4 haitusquare;332A hakatakana;30CF hakatakanahalfwidth;FF8A halantgurmukhi;0A4D hamzaarabic;0621 hamzadammaarabic;0621 064F hamzadammatanarabic;0621 064C hamzafathaarabic;0621 064E hamzafathatanarabic;0621 064B hamzalowarabic;0621 hamzalowkasraarabic;0621 0650 hamzalowkasratanarabic;0621 064D hamzasukunarabic;0621 0652 hangulfiller;3164 hardsigncyrillic;044A harpoonleftbarbup;21BC harpoonrightbarbup;21C0 hasquare;33CA hatafpatah;05B2 hatafpatah16;05B2 hatafpatah23;05B2 hatafpatah2f;05B2 hatafpatahhebrew;05B2 hatafpatahnarrowhebrew;05B2 hatafpatahquarterhebrew;05B2 hatafpatahwidehebrew;05B2 hatafqamats;05B3 hatafqamats1b;05B3 hatafqamats28;05B3 hatafqamats34;05B3 hatafqamatshebrew;05B3 hatafqamatsnarrowhebrew;05B3 hatafqamatsquarterhebrew;05B3 hatafqamatswidehebrew;05B3 hatafsegol;05B1 hatafsegol17;05B1 hatafsegol24;05B1 hatafsegol30;05B1 hatafsegolhebrew;05B1 hatafsegolnarrowhebrew;05B1 hatafsegolquarterhebrew;05B1 hatafsegolwidehebrew;05B1 hbar;0127 hbopomofo;310F hbrevebelow;1E2B hcedilla;1E29 hcircle;24D7 hcircumflex;0125 hdieresis;1E27 hdotaccent;1E23 hdotbelow;1E25 he;05D4 heart;2665 heartsuitblack;2665 heartsuitwhite;2661 hedagesh;FB34 hedageshhebrew;FB34 hehaltonearabic;06C1 heharabic;0647 hehebrew;05D4 hehfinalaltonearabic;FBA7 hehfinalalttwoarabic;FEEA hehfinalarabic;FEEA hehhamzaabovefinalarabic;FBA5 hehhamzaaboveisolatedarabic;FBA4 hehinitialaltonearabic;FBA8 hehinitialarabic;FEEB hehiragana;3078 hehmedialaltonearabic;FBA9 hehmedialarabic;FEEC heiseierasquare;337B hekatakana;30D8 hekatakanahalfwidth;FF8D hekutaarusquare;3336 henghook;0267 herutusquare;3339 het;05D7 hethebrew;05D7 hhook;0266 hhooksuperior;02B1 hieuhacirclekorean;327B hieuhaparenkorean;321B hieuhcirclekorean;326D hieuhkorean;314E hieuhparenkorean;320D hihiragana;3072 hikatakana;30D2 hikatakanahalfwidth;FF8B hiriq;05B4 hiriq14;05B4 hiriq21;05B4 hiriq2d;05B4 hiriqhebrew;05B4 hiriqnarrowhebrew;05B4 hiriqquarterhebrew;05B4 hiriqwidehebrew;05B4 hlinebelow;1E96 hmonospace;FF48 hoarmenian;0570 hohipthai;0E2B hohiragana;307B hokatakana;30DB hokatakanahalfwidth;FF8E holam;05B9 holam19;05B9 holam26;05B9 holam32;05B9 holamhebrew;05B9 holamnarrowhebrew;05B9 holamquarterhebrew;05B9 holamwidehebrew;05B9 honokhukthai;0E2E hookabovecomb;0309 hookcmb;0309 hookpalatalizedbelowcmb;0321 hookretroflexbelowcmb;0322 hoonsquare;3342 horicoptic;03E9 horizontalbar;2015 horncmb;031B hotsprings;2668 house;2302 hparen;24A3 hsuperior;02B0 hturned;0265 huhiragana;3075 huiitosquare;3333 hukatakana;30D5 hukatakanahalfwidth;FF8C hungarumlaut;02DD hungarumlautcmb;030B hv;0195 hyphen;002D hypheninferior;F6E5 hyphenmonospace;FF0D hyphensmall;FE63 hyphensuperior;F6E6 hyphentwo;2010 i;0069 iacute;00ED iacyrillic;044F ibengali;0987 ibopomofo;3127 ibreve;012D icaron;01D0 icircle;24D8 icircumflex;00EE icyrillic;0456 idblgrave;0209 ideographearthcircle;328F ideographfirecircle;328B ideographicallianceparen;323F ideographiccallparen;323A ideographiccentrecircle;32A5 ideographicclose;3006 ideographiccomma;3001 ideographiccommaleft;FF64 ideographiccongratulationparen;3237 ideographiccorrectcircle;32A3 ideographicearthparen;322F ideographicenterpriseparen;323D ideographicexcellentcircle;329D ideographicfestivalparen;3240 ideographicfinancialcircle;3296 ideographicfinancialparen;3236 ideographicfireparen;322B ideographichaveparen;3232 ideographichighcircle;32A4 ideographiciterationmark;3005 ideographiclaborcircle;3298 ideographiclaborparen;3238 ideographicleftcircle;32A7 ideographiclowcircle;32A6 ideographicmedicinecircle;32A9 ideographicmetalparen;322E ideographicmoonparen;322A ideographicnameparen;3234 ideographicperiod;3002 ideographicprintcircle;329E ideographicreachparen;3243 ideographicrepresentparen;3239 ideographicresourceparen;323E ideographicrightcircle;32A8 ideographicsecretcircle;3299 ideographicselfparen;3242 ideographicsocietyparen;3233 ideographicspace;3000 ideographicspecialparen;3235 ideographicstockparen;3231 ideographicstudyparen;323B ideographicsunparen;3230 ideographicsuperviseparen;323C ideographicwaterparen;322C ideographicwoodparen;322D ideographiczero;3007 ideographmetalcircle;328E ideographmooncircle;328A ideographnamecircle;3294 ideographsuncircle;3290 ideographwatercircle;328C ideographwoodcircle;328D ideva;0907 idieresis;00EF idieresisacute;1E2F idieresiscyrillic;04E5 idotbelow;1ECB iebrevecyrillic;04D7 iecyrillic;0435 ieungacirclekorean;3275 ieungaparenkorean;3215 ieungcirclekorean;3267 ieungkorean;3147 ieungparenkorean;3207 igrave;00EC igujarati;0A87 igurmukhi;0A07 ihiragana;3044 ihookabove;1EC9 iibengali;0988 iicyrillic;0438 iideva;0908 iigujarati;0A88 iigurmukhi;0A08 iimatragurmukhi;0A40 iinvertedbreve;020B iishortcyrillic;0439 iivowelsignbengali;09C0 iivowelsigndeva;0940 iivowelsigngujarati;0AC0 ij;0133 ikatakana;30A4 ikatakanahalfwidth;FF72 ikorean;3163 ilde;02DC iluyhebrew;05AC imacron;012B imacroncyrillic;04E3 imageorapproximatelyequal;2253 imatragurmukhi;0A3F imonospace;FF49 increment;2206 infinity;221E iniarmenian;056B integral;222B integralbottom;2321 integralbt;2321 integralex;F8F5 integraltop;2320 integraltp;2320 intersection;2229 intisquare;3305 invbullet;25D8 invcircle;25D9 invsmileface;263B iocyrillic;0451 iogonek;012F iota;03B9 iotadieresis;03CA iotadieresistonos;0390 iotalatin;0269 iotatonos;03AF iparen;24A4 irigurmukhi;0A72 ismallhiragana;3043 ismallkatakana;30A3 ismallkatakanahalfwidth;FF68 issharbengali;09FA istroke;0268 isuperior;F6ED iterationhiragana;309D iterationkatakana;30FD itilde;0129 itildebelow;1E2D iubopomofo;3129 iucyrillic;044E ivowelsignbengali;09BF ivowelsigndeva;093F ivowelsigngujarati;0ABF izhitsacyrillic;0475 izhitsadblgravecyrillic;0477 j;006A jaarmenian;0571 jabengali;099C jadeva;091C jagujarati;0A9C jagurmukhi;0A1C jbopomofo;3110 jcaron;01F0 jcircle;24D9 jcircumflex;0135 jcrossedtail;029D jdotlessstroke;025F jecyrillic;0458 jeemarabic;062C jeemfinalarabic;FE9E jeeminitialarabic;FE9F jeemmedialarabic;FEA0 jeharabic;0698 jehfinalarabic;FB8B jhabengali;099D jhadeva;091D jhagujarati;0A9D jhagurmukhi;0A1D jheharmenian;057B jis;3004 jmonospace;FF4A jparen;24A5 jsuperior;02B2 k;006B kabashkircyrillic;04A1 kabengali;0995 kacute;1E31 kacyrillic;043A kadescendercyrillic;049B kadeva;0915 kaf;05DB kafarabic;0643 kafdagesh;FB3B kafdageshhebrew;FB3B kaffinalarabic;FEDA kafhebrew;05DB kafinitialarabic;FEDB kafmedialarabic;FEDC kafrafehebrew;FB4D kagujarati;0A95 kagurmukhi;0A15 kahiragana;304B kahookcyrillic;04C4 kakatakana;30AB kakatakanahalfwidth;FF76 kappa;03BA kappasymbolgreek;03F0 kapyeounmieumkorean;3171 kapyeounphieuphkorean;3184 kapyeounpieupkorean;3178 kapyeounssangpieupkorean;3179 karoriisquare;330D kashidaautoarabic;0640 kashidaautonosidebearingarabic;0640 kasmallkatakana;30F5 kasquare;3384 kasraarabic;0650 kasratanarabic;064D kastrokecyrillic;049F katahiraprolongmarkhalfwidth;FF70 kaverticalstrokecyrillic;049D kbopomofo;310E kcalsquare;3389 kcaron;01E9 kcedilla;0137 kcircle;24DA kcommaaccent;0137 kdotbelow;1E33 keharmenian;0584 kehiragana;3051 kekatakana;30B1 kekatakanahalfwidth;FF79 kenarmenian;056F kesmallkatakana;30F6 kgreenlandic;0138 khabengali;0996 khacyrillic;0445 khadeva;0916 khagujarati;0A96 khagurmukhi;0A16 khaharabic;062E khahfinalarabic;FEA6 khahinitialarabic;FEA7 khahmedialarabic;FEA8 kheicoptic;03E7 khhadeva;0959 khhagurmukhi;0A59 khieukhacirclekorean;3278 khieukhaparenkorean;3218 khieukhcirclekorean;326A khieukhkorean;314B khieukhparenkorean;320A khokhaithai;0E02 khokhonthai;0E05 khokhuatthai;0E03 khokhwaithai;0E04 khomutthai;0E5B khook;0199 khorakhangthai;0E06 khzsquare;3391 kihiragana;304D kikatakana;30AD kikatakanahalfwidth;FF77 kiroguramusquare;3315 kiromeetorusquare;3316 kirosquare;3314 kiyeokacirclekorean;326E kiyeokaparenkorean;320E kiyeokcirclekorean;3260 kiyeokkorean;3131 kiyeokparenkorean;3200 kiyeoksioskorean;3133 kjecyrillic;045C klinebelow;1E35 klsquare;3398 kmcubedsquare;33A6 kmonospace;FF4B kmsquaredsquare;33A2 kohiragana;3053 kohmsquare;33C0 kokaithai;0E01 kokatakana;30B3 kokatakanahalfwidth;FF7A kooposquare;331E koppacyrillic;0481 koreanstandardsymbol;327F koroniscmb;0343 kparen;24A6 kpasquare;33AA ksicyrillic;046F ktsquare;33CF kturned;029E kuhiragana;304F kukatakana;30AF kukatakanahalfwidth;FF78 kvsquare;33B8 kwsquare;33BE l;006C labengali;09B2 lacute;013A ladeva;0932 lagujarati;0AB2 lagurmukhi;0A32 lakkhangyaothai;0E45 lamaleffinalarabic;FEFC lamalefhamzaabovefinalarabic;FEF8 lamalefhamzaaboveisolatedarabic;FEF7 lamalefhamzabelowfinalarabic;FEFA lamalefhamzabelowisolatedarabic;FEF9 lamalefisolatedarabic;FEFB lamalefmaddaabovefinalarabic;FEF6 lamalefmaddaaboveisolatedarabic;FEF5 lamarabic;0644 lambda;03BB lambdastroke;019B lamed;05DC lameddagesh;FB3C lameddageshhebrew;FB3C lamedhebrew;05DC lamedholam;05DC 05B9 lamedholamdagesh;05DC 05B9 05BC lamedholamdageshhebrew;05DC 05B9 05BC lamedholamhebrew;05DC 05B9 lamfinalarabic;FEDE lamhahinitialarabic;FCCA laminitialarabic;FEDF lamjeeminitialarabic;FCC9 lamkhahinitialarabic;FCCB lamlamhehisolatedarabic;FDF2 lammedialarabic;FEE0 lammeemhahinitialarabic;FD88 lammeeminitialarabic;FCCC lammeemjeeminitialarabic;FEDF FEE4 FEA0 lammeemkhahinitialarabic;FEDF FEE4 FEA8 largecircle;25EF lbar;019A lbelt;026C lbopomofo;310C lcaron;013E lcedilla;013C lcircle;24DB lcircumflexbelow;1E3D lcommaaccent;013C ldot;0140 ldotaccent;0140 ldotbelow;1E37 ldotbelowmacron;1E39 leftangleabovecmb;031A lefttackbelowcmb;0318 less;003C lessequal;2264 lessequalorgreater;22DA lessmonospace;FF1C lessorequivalent;2272 lessorgreater;2276 lessoverequal;2266 lesssmall;FE64 lezh;026E lfblock;258C lhookretroflex;026D lira;20A4 liwnarmenian;056C lj;01C9 ljecyrillic;0459 ll;F6C0 lladeva;0933 llagujarati;0AB3 llinebelow;1E3B llladeva;0934 llvocalicbengali;09E1 llvocalicdeva;0961 llvocalicvowelsignbengali;09E3 llvocalicvowelsigndeva;0963 lmiddletilde;026B lmonospace;FF4C lmsquare;33D0 lochulathai;0E2C logicaland;2227 logicalnot;00AC logicalnotreversed;2310 logicalor;2228 lolingthai;0E25 longs;017F lowlinecenterline;FE4E lowlinecmb;0332 lowlinedashed;FE4D lozenge;25CA lparen;24A7 lslash;0142 lsquare;2113 lsuperior;F6EE ltshade;2591 luthai;0E26 lvocalicbengali;098C lvocalicdeva;090C lvocalicvowelsignbengali;09E2 lvocalicvowelsigndeva;0962 lxsquare;33D3 m;006D mabengali;09AE macron;00AF macronbelowcmb;0331 macroncmb;0304 macronlowmod;02CD macronmonospace;FFE3 macute;1E3F madeva;092E magujarati;0AAE magurmukhi;0A2E mahapakhhebrew;05A4 mahapakhlefthebrew;05A4 mahiragana;307E maichattawalowleftthai;F895 maichattawalowrightthai;F894 maichattawathai;0E4B maichattawaupperleftthai;F893 maieklowleftthai;F88C maieklowrightthai;F88B maiekthai;0E48 maiekupperleftthai;F88A maihanakatleftthai;F884 maihanakatthai;0E31 maitaikhuleftthai;F889 maitaikhuthai;0E47 maitholowleftthai;F88F maitholowrightthai;F88E maithothai;0E49 maithoupperleftthai;F88D maitrilowleftthai;F892 maitrilowrightthai;F891 maitrithai;0E4A maitriupperleftthai;F890 maiyamokthai;0E46 makatakana;30DE makatakanahalfwidth;FF8F male;2642 mansyonsquare;3347 maqafhebrew;05BE mars;2642 masoracirclehebrew;05AF masquare;3383 mbopomofo;3107 mbsquare;33D4 mcircle;24DC mcubedsquare;33A5 mdotaccent;1E41 mdotbelow;1E43 meemarabic;0645 meemfinalarabic;FEE2 meeminitialarabic;FEE3 meemmedialarabic;FEE4 meemmeeminitialarabic;FCD1 meemmeemisolatedarabic;FC48 meetorusquare;334D mehiragana;3081 meizierasquare;337E mekatakana;30E1 mekatakanahalfwidth;FF92 mem;05DE memdagesh;FB3E memdageshhebrew;FB3E memhebrew;05DE menarmenian;0574 merkhahebrew;05A5 merkhakefulahebrew;05A6 merkhakefulalefthebrew;05A6 merkhalefthebrew;05A5 mhook;0271 mhzsquare;3392 middledotkatakanahalfwidth;FF65 middot;00B7 mieumacirclekorean;3272 mieumaparenkorean;3212 mieumcirclekorean;3264 mieumkorean;3141 mieumpansioskorean;3170 mieumparenkorean;3204 mieumpieupkorean;316E mieumsioskorean;316F mihiragana;307F mikatakana;30DF mikatakanahalfwidth;FF90 minus;2212 minusbelowcmb;0320 minuscircle;2296 minusmod;02D7 minusplus;2213 minute;2032 miribaarusquare;334A mirisquare;3349 mlonglegturned;0270 mlsquare;3396 mmcubedsquare;33A3 mmonospace;FF4D mmsquaredsquare;339F mohiragana;3082 mohmsquare;33C1 mokatakana;30E2 mokatakanahalfwidth;FF93 molsquare;33D6 momathai;0E21 moverssquare;33A7 moverssquaredsquare;33A8 mparen;24A8 mpasquare;33AB mssquare;33B3 msuperior;F6EF mturned;026F mu;00B5 mu1;00B5 muasquare;3382 muchgreater;226B muchless;226A mufsquare;338C mugreek;03BC mugsquare;338D muhiragana;3080 mukatakana;30E0 mukatakanahalfwidth;FF91 mulsquare;3395 multiply;00D7 mumsquare;339B munahhebrew;05A3 munahlefthebrew;05A3 musicalnote;266A musicalnotedbl;266B musicflatsign;266D musicsharpsign;266F mussquare;33B2 muvsquare;33B6 muwsquare;33BC mvmegasquare;33B9 mvsquare;33B7 mwmegasquare;33BF mwsquare;33BD n;006E nabengali;09A8 nabla;2207 nacute;0144 nadeva;0928 nagujarati;0AA8 nagurmukhi;0A28 nahiragana;306A nakatakana;30CA nakatakanahalfwidth;FF85 napostrophe;0149 nasquare;3381 nbopomofo;310B nbspace;00A0 ncaron;0148 ncedilla;0146 ncircle;24DD ncircumflexbelow;1E4B ncommaaccent;0146 ndotaccent;1E45 ndotbelow;1E47 nehiragana;306D nekatakana;30CD nekatakanahalfwidth;FF88 newsheqelsign;20AA nfsquare;338B ngabengali;0999 ngadeva;0919 ngagujarati;0A99 ngagurmukhi;0A19 ngonguthai;0E07 nhiragana;3093 nhookleft;0272 nhookretroflex;0273 nieunacirclekorean;326F nieunaparenkorean;320F nieuncieuckorean;3135 nieuncirclekorean;3261 nieunhieuhkorean;3136 nieunkorean;3134 nieunpansioskorean;3168 nieunparenkorean;3201 nieunsioskorean;3167 nieuntikeutkorean;3166 nihiragana;306B nikatakana;30CB nikatakanahalfwidth;FF86 nikhahitleftthai;F899 nikhahitthai;0E4D nine;0039 ninearabic;0669 ninebengali;09EF ninecircle;2468 ninecircleinversesansserif;2792 ninedeva;096F ninegujarati;0AEF ninegurmukhi;0A6F ninehackarabic;0669 ninehangzhou;3029 nineideographicparen;3228 nineinferior;2089 ninemonospace;FF19 nineoldstyle;F739 nineparen;247C nineperiod;2490 ninepersian;06F9 nineroman;2178 ninesuperior;2079 nineteencircle;2472 nineteenparen;2486 nineteenperiod;249A ninethai;0E59 nj;01CC njecyrillic;045A nkatakana;30F3 nkatakanahalfwidth;FF9D nlegrightlong;019E nlinebelow;1E49 nmonospace;FF4E nmsquare;339A nnabengali;09A3 nnadeva;0923 nnagujarati;0AA3 nnagurmukhi;0A23 nnnadeva;0929 nohiragana;306E nokatakana;30CE nokatakanahalfwidth;FF89 nonbreakingspace;00A0 nonenthai;0E13 nonuthai;0E19 noonarabic;0646 noonfinalarabic;FEE6 noonghunnaarabic;06BA noonghunnafinalarabic;FB9F noonhehinitialarabic;FEE7 FEEC nooninitialarabic;FEE7 noonjeeminitialarabic;FCD2 noonjeemisolatedarabic;FC4B noonmedialarabic;FEE8 noonmeeminitialarabic;FCD5 noonmeemisolatedarabic;FC4E noonnoonfinalarabic;FC8D notcontains;220C notelement;2209 notelementof;2209 notequal;2260 notgreater;226F notgreaternorequal;2271 notgreaternorless;2279 notidentical;2262 notless;226E notlessnorequal;2270 notparallel;2226 notprecedes;2280 notsubset;2284 notsucceeds;2281 notsuperset;2285 nowarmenian;0576 nparen;24A9 nssquare;33B1 nsuperior;207F ntilde;00F1 nu;03BD nuhiragana;306C nukatakana;30CC nukatakanahalfwidth;FF87 nuktabengali;09BC nuktadeva;093C nuktagujarati;0ABC nuktagurmukhi;0A3C numbersign;0023 numbersignmonospace;FF03 numbersignsmall;FE5F numeralsigngreek;0374 numeralsignlowergreek;0375 numero;2116 nun;05E0 nundagesh;FB40 nundageshhebrew;FB40 nunhebrew;05E0 nvsquare;33B5 nwsquare;33BB nyabengali;099E nyadeva;091E nyagujarati;0A9E nyagurmukhi;0A1E o;006F oacute;00F3 oangthai;0E2D obarred;0275 obarredcyrillic;04E9 obarreddieresiscyrillic;04EB obengali;0993 obopomofo;311B obreve;014F ocandradeva;0911 ocandragujarati;0A91 ocandravowelsigndeva;0949 ocandravowelsigngujarati;0AC9 ocaron;01D2 ocircle;24DE ocircumflex;00F4 ocircumflexacute;1ED1 ocircumflexdotbelow;1ED9 ocircumflexgrave;1ED3 ocircumflexhookabove;1ED5 ocircumflextilde;1ED7 ocyrillic;043E odblacute;0151 odblgrave;020D odeva;0913 odieresis;00F6 odieresiscyrillic;04E7 odotbelow;1ECD oe;0153 oekorean;315A ogonek;02DB ogonekcmb;0328 ograve;00F2 ogujarati;0A93 oharmenian;0585 ohiragana;304A ohookabove;1ECF ohorn;01A1 ohornacute;1EDB ohorndotbelow;1EE3 ohorngrave;1EDD ohornhookabove;1EDF ohorntilde;1EE1 ohungarumlaut;0151 oi;01A3 oinvertedbreve;020F okatakana;30AA okatakanahalfwidth;FF75 okorean;3157 olehebrew;05AB omacron;014D omacronacute;1E53 omacrongrave;1E51 omdeva;0950 omega;03C9 omega1;03D6 omegacyrillic;0461 omegalatinclosed;0277 omegaroundcyrillic;047B omegatitlocyrillic;047D omegatonos;03CE omgujarati;0AD0 omicron;03BF omicrontonos;03CC omonospace;FF4F one;0031 onearabic;0661 onebengali;09E7 onecircle;2460 onecircleinversesansserif;278A onedeva;0967 onedotenleader;2024 oneeighth;215B onefitted;F6DC onegujarati;0AE7 onegurmukhi;0A67 onehackarabic;0661 onehalf;00BD onehangzhou;3021 oneideographicparen;3220 oneinferior;2081 onemonospace;FF11 onenumeratorbengali;09F4 oneoldstyle;F731 oneparen;2474 oneperiod;2488 onepersian;06F1 onequarter;00BC oneroman;2170 onesuperior;00B9 onethai;0E51 onethird;2153 oogonek;01EB oogonekmacron;01ED oogurmukhi;0A13 oomatragurmukhi;0A4B oopen;0254 oparen;24AA openbullet;25E6 option;2325 ordfeminine;00AA ordmasculine;00BA orthogonal;221F oshortdeva;0912 oshortvowelsigndeva;094A oslash;00F8 oslashacute;01FF osmallhiragana;3049 osmallkatakana;30A9 osmallkatakanahalfwidth;FF6B ostrokeacute;01FF osuperior;F6F0 otcyrillic;047F otilde;00F5 otildeacute;1E4D otildedieresis;1E4F oubopomofo;3121 overline;203E overlinecenterline;FE4A overlinecmb;0305 overlinedashed;FE49 overlinedblwavy;FE4C overlinewavy;FE4B overscore;00AF ovowelsignbengali;09CB ovowelsigndeva;094B ovowelsigngujarati;0ACB p;0070 paampssquare;3380 paasentosquare;332B pabengali;09AA pacute;1E55 padeva;092A pagedown;21DF pageup;21DE pagujarati;0AAA pagurmukhi;0A2A pahiragana;3071 paiyannoithai;0E2F pakatakana;30D1 palatalizationcyrilliccmb;0484 palochkacyrillic;04C0 pansioskorean;317F paragraph;00B6 parallel;2225 parenleft;0028 parenleftaltonearabic;FD3E parenleftbt;F8ED parenleftex;F8EC parenleftinferior;208D parenleftmonospace;FF08 parenleftsmall;FE59 parenleftsuperior;207D parenlefttp;F8EB parenleftvertical;FE35 parenright;0029 parenrightaltonearabic;FD3F parenrightbt;F8F8 parenrightex;F8F7 parenrightinferior;208E parenrightmonospace;FF09 parenrightsmall;FE5A parenrightsuperior;207E parenrighttp;F8F6 parenrightvertical;FE36 partialdiff;2202 paseqhebrew;05C0 pashtahebrew;0599 pasquare;33A9 patah;05B7 patah11;05B7 patah1d;05B7 patah2a;05B7 patahhebrew;05B7 patahnarrowhebrew;05B7 patahquarterhebrew;05B7 patahwidehebrew;05B7 pazerhebrew;05A1 pbopomofo;3106 pcircle;24DF pdotaccent;1E57 pe;05E4 pecyrillic;043F pedagesh;FB44 pedageshhebrew;FB44 peezisquare;333B pefinaldageshhebrew;FB43 peharabic;067E peharmenian;057A pehebrew;05E4 pehfinalarabic;FB57 pehinitialarabic;FB58 pehiragana;307A pehmedialarabic;FB59 pekatakana;30DA pemiddlehookcyrillic;04A7 perafehebrew;FB4E percent;0025 percentarabic;066A percentmonospace;FF05 percentsmall;FE6A period;002E periodarmenian;0589 periodcentered;00B7 periodhalfwidth;FF61 periodinferior;F6E7 periodmonospace;FF0E periodsmall;FE52 periodsuperior;F6E8 perispomenigreekcmb;0342 perpendicular;22A5 perthousand;2030 peseta;20A7 pfsquare;338A phabengali;09AB phadeva;092B phagujarati;0AAB phagurmukhi;0A2B phi;03C6 phi1;03D5 phieuphacirclekorean;327A phieuphaparenkorean;321A phieuphcirclekorean;326C phieuphkorean;314D phieuphparenkorean;320C philatin;0278 phinthuthai;0E3A phisymbolgreek;03D5 phook;01A5 phophanthai;0E1E phophungthai;0E1C phosamphaothai;0E20 pi;03C0 pieupacirclekorean;3273 pieupaparenkorean;3213 pieupcieuckorean;3176 pieupcirclekorean;3265 pieupkiyeokkorean;3172 pieupkorean;3142 pieupparenkorean;3205 pieupsioskiyeokkorean;3174 pieupsioskorean;3144 pieupsiostikeutkorean;3175 pieupthieuthkorean;3177 pieuptikeutkorean;3173 pihiragana;3074 pikatakana;30D4 pisymbolgreek;03D6 piwrarmenian;0583 plus;002B plusbelowcmb;031F pluscircle;2295 plusminus;00B1 plusmod;02D6 plusmonospace;FF0B plussmall;FE62 plussuperior;207A pmonospace;FF50 pmsquare;33D8 pohiragana;307D pointingindexdownwhite;261F pointingindexleftwhite;261C pointingindexrightwhite;261E pointingindexupwhite;261D pokatakana;30DD poplathai;0E1B postalmark;3012 postalmarkface;3020 pparen;24AB precedes;227A prescription;211E primemod;02B9 primereversed;2035 product;220F projective;2305 prolongedkana;30FC propellor;2318 propersubset;2282 propersuperset;2283 proportion;2237 proportional;221D psi;03C8 psicyrillic;0471 psilipneumatacyrilliccmb;0486 pssquare;33B0 puhiragana;3077 pukatakana;30D7 pvsquare;33B4 pwsquare;33BA q;0071 qadeva;0958 qadmahebrew;05A8 qafarabic;0642 qaffinalarabic;FED6 qafinitialarabic;FED7 qafmedialarabic;FED8 qamats;05B8 qamats10;05B8 qamats1a;05B8 qamats1c;05B8 qamats27;05B8 qamats29;05B8 qamats33;05B8 qamatsde;05B8 qamatshebrew;05B8 qamatsnarrowhebrew;05B8 qamatsqatanhebrew;05B8 qamatsqatannarrowhebrew;05B8 qamatsqatanquarterhebrew;05B8 qamatsqatanwidehebrew;05B8 qamatsquarterhebrew;05B8 qamatswidehebrew;05B8 qarneyparahebrew;059F qbopomofo;3111 qcircle;24E0 qhook;02A0 qmonospace;FF51 qof;05E7 qofdagesh;FB47 qofdageshhebrew;FB47 qofhatafpatah;05E7 05B2 qofhatafpatahhebrew;05E7 05B2 qofhatafsegol;05E7 05B1 qofhatafsegolhebrew;05E7 05B1 qofhebrew;05E7 qofhiriq;05E7 05B4 qofhiriqhebrew;05E7 05B4 qofholam;05E7 05B9 qofholamhebrew;05E7 05B9 qofpatah;05E7 05B7 qofpatahhebrew;05E7 05B7 qofqamats;05E7 05B8 qofqamatshebrew;05E7 05B8 qofqubuts;05E7 05BB qofqubutshebrew;05E7 05BB qofsegol;05E7 05B6 qofsegolhebrew;05E7 05B6 qofsheva;05E7 05B0 qofshevahebrew;05E7 05B0 qoftsere;05E7 05B5 qoftserehebrew;05E7 05B5 qparen;24AC quarternote;2669 qubuts;05BB qubuts18;05BB qubuts25;05BB qubuts31;05BB qubutshebrew;05BB qubutsnarrowhebrew;05BB qubutsquarterhebrew;05BB qubutswidehebrew;05BB question;003F questionarabic;061F questionarmenian;055E questiondown;00BF questiondownsmall;F7BF questiongreek;037E questionmonospace;FF1F questionsmall;F73F quotedbl;0022 quotedblbase;201E quotedblleft;201C quotedblmonospace;FF02 quotedblprime;301E quotedblprimereversed;301D quotedblright;201D quoteleft;2018 quoteleftreversed;201B quotereversed;201B quoteright;2019 quoterightn;0149 quotesinglbase;201A quotesingle;0027 quotesinglemonospace;FF07 r;0072 raarmenian;057C rabengali;09B0 racute;0155 radeva;0930 radical;221A radicalex;F8E5 radoverssquare;33AE radoverssquaredsquare;33AF radsquare;33AD rafe;05BF rafehebrew;05BF ragujarati;0AB0 ragurmukhi;0A30 rahiragana;3089 rakatakana;30E9 rakatakanahalfwidth;FF97 ralowerdiagonalbengali;09F1 ramiddlediagonalbengali;09F0 ramshorn;0264 ratio;2236 rbopomofo;3116 rcaron;0159 rcedilla;0157 rcircle;24E1 rcommaaccent;0157 rdblgrave;0211 rdotaccent;1E59 rdotbelow;1E5B rdotbelowmacron;1E5D referencemark;203B reflexsubset;2286 reflexsuperset;2287 registered;00AE registersans;F8E8 registerserif;F6DA reharabic;0631 reharmenian;0580 rehfinalarabic;FEAE rehiragana;308C rehyehaleflamarabic;0631 FEF3 FE8E 0644 rekatakana;30EC rekatakanahalfwidth;FF9A resh;05E8 reshdageshhebrew;FB48 reshhatafpatah;05E8 05B2 reshhatafpatahhebrew;05E8 05B2 reshhatafsegol;05E8 05B1 reshhatafsegolhebrew;05E8 05B1 reshhebrew;05E8 reshhiriq;05E8 05B4 reshhiriqhebrew;05E8 05B4 reshholam;05E8 05B9 reshholamhebrew;05E8 05B9 reshpatah;05E8 05B7 reshpatahhebrew;05E8 05B7 reshqamats;05E8 05B8 reshqamatshebrew;05E8 05B8 reshqubuts;05E8 05BB reshqubutshebrew;05E8 05BB reshsegol;05E8 05B6 reshsegolhebrew;05E8 05B6 reshsheva;05E8 05B0 reshshevahebrew;05E8 05B0 reshtsere;05E8 05B5 reshtserehebrew;05E8 05B5 reversedtilde;223D reviahebrew;0597 reviamugrashhebrew;0597 revlogicalnot;2310 rfishhook;027E rfishhookreversed;027F rhabengali;09DD rhadeva;095D rho;03C1 rhook;027D rhookturned;027B rhookturnedsuperior;02B5 rhosymbolgreek;03F1 rhotichookmod;02DE rieulacirclekorean;3271 rieulaparenkorean;3211 rieulcirclekorean;3263 rieulhieuhkorean;3140 rieulkiyeokkorean;313A rieulkiyeoksioskorean;3169 rieulkorean;3139 rieulmieumkorean;313B rieulpansioskorean;316C rieulparenkorean;3203 rieulphieuphkorean;313F rieulpieupkorean;313C rieulpieupsioskorean;316B rieulsioskorean;313D rieulthieuthkorean;313E rieultikeutkorean;316A rieulyeorinhieuhkorean;316D rightangle;221F righttackbelowcmb;0319 righttriangle;22BF rihiragana;308A rikatakana;30EA rikatakanahalfwidth;FF98 ring;02DA ringbelowcmb;0325 ringcmb;030A ringhalfleft;02BF ringhalfleftarmenian;0559 ringhalfleftbelowcmb;031C ringhalfleftcentered;02D3 ringhalfright;02BE ringhalfrightbelowcmb;0339 ringhalfrightcentered;02D2 rinvertedbreve;0213 rittorusquare;3351 rlinebelow;1E5F rlongleg;027C rlonglegturned;027A rmonospace;FF52 rohiragana;308D rokatakana;30ED rokatakanahalfwidth;FF9B roruathai;0E23 rparen;24AD rrabengali;09DC rradeva;0931 rragurmukhi;0A5C rreharabic;0691 rrehfinalarabic;FB8D rrvocalicbengali;09E0 rrvocalicdeva;0960 rrvocalicgujarati;0AE0 rrvocalicvowelsignbengali;09C4 rrvocalicvowelsigndeva;0944 rrvocalicvowelsigngujarati;0AC4 rsuperior;F6F1 rtblock;2590 rturned;0279 rturnedsuperior;02B4 ruhiragana;308B rukatakana;30EB rukatakanahalfwidth;FF99 rupeemarkbengali;09F2 rupeesignbengali;09F3 rupiah;F6DD ruthai;0E24 rvocalicbengali;098B rvocalicdeva;090B rvocalicgujarati;0A8B rvocalicvowelsignbengali;09C3 rvocalicvowelsigndeva;0943 rvocalicvowelsigngujarati;0AC3 s;0073 sabengali;09B8 sacute;015B sacutedotaccent;1E65 sadarabic;0635 sadeva;0938 sadfinalarabic;FEBA sadinitialarabic;FEBB sadmedialarabic;FEBC sagujarati;0AB8 sagurmukhi;0A38 sahiragana;3055 sakatakana;30B5 sakatakanahalfwidth;FF7B sallallahoualayhewasallamarabic;FDFA samekh;05E1 samekhdagesh;FB41 samekhdageshhebrew;FB41 samekhhebrew;05E1 saraaathai;0E32 saraaethai;0E41 saraaimaimalaithai;0E44 saraaimaimuanthai;0E43 saraamthai;0E33 saraathai;0E30 saraethai;0E40 saraiileftthai;F886 saraiithai;0E35 saraileftthai;F885 saraithai;0E34 saraothai;0E42 saraueeleftthai;F888 saraueethai;0E37 saraueleftthai;F887 sarauethai;0E36 sarauthai;0E38 sarauuthai;0E39 sbopomofo;3119 scaron;0161 scarondotaccent;1E67 scedilla;015F schwa;0259 schwacyrillic;04D9 schwadieresiscyrillic;04DB schwahook;025A scircle;24E2 scircumflex;015D scommaaccent;0219 sdotaccent;1E61 sdotbelow;1E63 sdotbelowdotaccent;1E69 seagullbelowcmb;033C second;2033 secondtonechinese;02CA section;00A7 seenarabic;0633 seenfinalarabic;FEB2 seeninitialarabic;FEB3 seenmedialarabic;FEB4 segol;05B6 segol13;05B6 segol1f;05B6 segol2c;05B6 segolhebrew;05B6 segolnarrowhebrew;05B6 segolquarterhebrew;05B6 segoltahebrew;0592 segolwidehebrew;05B6 seharmenian;057D sehiragana;305B sekatakana;30BB sekatakanahalfwidth;FF7E semicolon;003B semicolonarabic;061B semicolonmonospace;FF1B semicolonsmall;FE54 semivoicedmarkkana;309C semivoicedmarkkanahalfwidth;FF9F sentisquare;3322 sentosquare;3323 seven;0037 sevenarabic;0667 sevenbengali;09ED sevencircle;2466 sevencircleinversesansserif;2790 sevendeva;096D seveneighths;215E sevengujarati;0AED sevengurmukhi;0A6D sevenhackarabic;0667 sevenhangzhou;3027 sevenideographicparen;3226 seveninferior;2087 sevenmonospace;FF17 sevenoldstyle;F737 sevenparen;247A sevenperiod;248E sevenpersian;06F7 sevenroman;2176 sevensuperior;2077 seventeencircle;2470 seventeenparen;2484 seventeenperiod;2498 seventhai;0E57 sfthyphen;00AD shaarmenian;0577 shabengali;09B6 shacyrillic;0448 shaddaarabic;0651 shaddadammaarabic;FC61 shaddadammatanarabic;FC5E shaddafathaarabic;FC60 shaddafathatanarabic;0651 064B shaddakasraarabic;FC62 shaddakasratanarabic;FC5F shade;2592 shadedark;2593 shadelight;2591 shademedium;2592 shadeva;0936 shagujarati;0AB6 shagurmukhi;0A36 shalshelethebrew;0593 shbopomofo;3115 shchacyrillic;0449 sheenarabic;0634 sheenfinalarabic;FEB6 sheeninitialarabic;FEB7 sheenmedialarabic;FEB8 sheicoptic;03E3 sheqel;20AA sheqelhebrew;20AA sheva;05B0 sheva115;05B0 sheva15;05B0 sheva22;05B0 sheva2e;05B0 shevahebrew;05B0 shevanarrowhebrew;05B0 shevaquarterhebrew;05B0 shevawidehebrew;05B0 shhacyrillic;04BB shimacoptic;03ED shin;05E9 shindagesh;FB49 shindageshhebrew;FB49 shindageshshindot;FB2C shindageshshindothebrew;FB2C shindageshsindot;FB2D shindageshsindothebrew;FB2D shindothebrew;05C1 shinhebrew;05E9 shinshindot;FB2A shinshindothebrew;FB2A shinsindot;FB2B shinsindothebrew;FB2B shook;0282 sigma;03C3 sigma1;03C2 sigmafinal;03C2 sigmalunatesymbolgreek;03F2 sihiragana;3057 sikatakana;30B7 sikatakanahalfwidth;FF7C siluqhebrew;05BD siluqlefthebrew;05BD similar;223C sindothebrew;05C2 siosacirclekorean;3274 siosaparenkorean;3214 sioscieuckorean;317E sioscirclekorean;3266 sioskiyeokkorean;317A sioskorean;3145 siosnieunkorean;317B siosparenkorean;3206 siospieupkorean;317D siostikeutkorean;317C six;0036 sixarabic;0666 sixbengali;09EC sixcircle;2465 sixcircleinversesansserif;278F sixdeva;096C sixgujarati;0AEC sixgurmukhi;0A6C sixhackarabic;0666 sixhangzhou;3026 sixideographicparen;3225 sixinferior;2086 sixmonospace;FF16 sixoldstyle;F736 sixparen;2479 sixperiod;248D sixpersian;06F6 sixroman;2175 sixsuperior;2076 sixteencircle;246F sixteencurrencydenominatorbengali;09F9 sixteenparen;2483 sixteenperiod;2497 sixthai;0E56 slash;002F slashmonospace;FF0F slong;017F slongdotaccent;1E9B smileface;263A smonospace;FF53 sofpasuqhebrew;05C3 softhyphen;00AD softsigncyrillic;044C sohiragana;305D sokatakana;30BD sokatakanahalfwidth;FF7F soliduslongoverlaycmb;0338 solidusshortoverlaycmb;0337 sorusithai;0E29 sosalathai;0E28 sosothai;0E0B sosuathai;0E2A space;0020 spacehackarabic;0020 spade;2660 spadesuitblack;2660 spadesuitwhite;2664 sparen;24AE squarebelowcmb;033B squarecc;33C4 squarecm;339D squarediagonalcrosshatchfill;25A9 squarehorizontalfill;25A4 squarekg;338F squarekm;339E squarekmcapital;33CE squareln;33D1 squarelog;33D2 squaremg;338E squaremil;33D5 squaremm;339C squaremsquared;33A1 squareorthogonalcrosshatchfill;25A6 squareupperlefttolowerrightfill;25A7 squareupperrighttolowerleftfill;25A8 squareverticalfill;25A5 squarewhitewithsmallblack;25A3 srsquare;33DB ssabengali;09B7 ssadeva;0937 ssagujarati;0AB7 ssangcieuckorean;3149 ssanghieuhkorean;3185 ssangieungkorean;3180 ssangkiyeokkorean;3132 ssangnieunkorean;3165 ssangpieupkorean;3143 ssangsioskorean;3146 ssangtikeutkorean;3138 ssuperior;F6F2 sterling;00A3 sterlingmonospace;FFE1 strokelongoverlaycmb;0336 strokeshortoverlaycmb;0335 subset;2282 subsetnotequal;228A subsetorequal;2286 succeeds;227B suchthat;220B suhiragana;3059 sukatakana;30B9 sukatakanahalfwidth;FF7D sukunarabic;0652 summation;2211 sun;263C superset;2283 supersetnotequal;228B supersetorequal;2287 svsquare;33DC syouwaerasquare;337C t;0074 tabengali;09A4 tackdown;22A4 tackleft;22A3 tadeva;0924 tagujarati;0AA4 tagurmukhi;0A24 taharabic;0637 tahfinalarabic;FEC2 tahinitialarabic;FEC3 tahiragana;305F tahmedialarabic;FEC4 taisyouerasquare;337D takatakana;30BF takatakanahalfwidth;FF80 tatweelarabic;0640 tau;03C4 tav;05EA tavdages;FB4A tavdagesh;FB4A tavdageshhebrew;FB4A tavhebrew;05EA tbar;0167 tbopomofo;310A tcaron;0165 tccurl;02A8 tcedilla;0163 tcheharabic;0686 tchehfinalarabic;FB7B tchehinitialarabic;FB7C tchehmedialarabic;FB7D tchehmeeminitialarabic;FB7C FEE4 tcircle;24E3 tcircumflexbelow;1E71 tcommaaccent;0163 tdieresis;1E97 tdotaccent;1E6B tdotbelow;1E6D tecyrillic;0442 tedescendercyrillic;04AD teharabic;062A tehfinalarabic;FE96 tehhahinitialarabic;FCA2 tehhahisolatedarabic;FC0C tehinitialarabic;FE97 tehiragana;3066 tehjeeminitialarabic;FCA1 tehjeemisolatedarabic;FC0B tehmarbutaarabic;0629 tehmarbutafinalarabic;FE94 tehmedialarabic;FE98 tehmeeminitialarabic;FCA4 tehmeemisolatedarabic;FC0E tehnoonfinalarabic;FC73 tekatakana;30C6 tekatakanahalfwidth;FF83 telephone;2121 telephoneblack;260E telishagedolahebrew;05A0 telishaqetanahebrew;05A9 tencircle;2469 tenideographicparen;3229 tenparen;247D tenperiod;2491 tenroman;2179 tesh;02A7 tet;05D8 tetdagesh;FB38 tetdageshhebrew;FB38 tethebrew;05D8 tetsecyrillic;04B5 tevirhebrew;059B tevirlefthebrew;059B thabengali;09A5 thadeva;0925 thagujarati;0AA5 thagurmukhi;0A25 thalarabic;0630 thalfinalarabic;FEAC thanthakhatlowleftthai;F898 thanthakhatlowrightthai;F897 thanthakhatthai;0E4C thanthakhatupperleftthai;F896 theharabic;062B thehfinalarabic;FE9A thehinitialarabic;FE9B thehmedialarabic;FE9C thereexists;2203 therefore;2234 theta;03B8 theta1;03D1 thetasymbolgreek;03D1 thieuthacirclekorean;3279 thieuthaparenkorean;3219 thieuthcirclekorean;326B thieuthkorean;314C thieuthparenkorean;320B thirteencircle;246C thirteenparen;2480 thirteenperiod;2494 thonangmonthothai;0E11 thook;01AD thophuthaothai;0E12 thorn;00FE thothahanthai;0E17 thothanthai;0E10 thothongthai;0E18 thothungthai;0E16 thousandcyrillic;0482 thousandsseparatorarabic;066C thousandsseparatorpersian;066C three;0033 threearabic;0663 threebengali;09E9 threecircle;2462 threecircleinversesansserif;278C threedeva;0969 threeeighths;215C threegujarati;0AE9 threegurmukhi;0A69 threehackarabic;0663 threehangzhou;3023 threeideographicparen;3222 threeinferior;2083 threemonospace;FF13 threenumeratorbengali;09F6 threeoldstyle;F733 threeparen;2476 threeperiod;248A threepersian;06F3 threequarters;00BE threequartersemdash;F6DE threeroman;2172 threesuperior;00B3 threethai;0E53 thzsquare;3394 tihiragana;3061 tikatakana;30C1 tikatakanahalfwidth;FF81 tikeutacirclekorean;3270 tikeutaparenkorean;3210 tikeutcirclekorean;3262 tikeutkorean;3137 tikeutparenkorean;3202 tilde;02DC tildebelowcmb;0330 tildecmb;0303 tildecomb;0303 tildedoublecmb;0360 tildeoperator;223C tildeoverlaycmb;0334 tildeverticalcmb;033E timescircle;2297 tipehahebrew;0596 tipehalefthebrew;0596 tippigurmukhi;0A70 titlocyrilliccmb;0483 tiwnarmenian;057F tlinebelow;1E6F tmonospace;FF54 toarmenian;0569 tohiragana;3068 tokatakana;30C8 tokatakanahalfwidth;FF84 tonebarextrahighmod;02E5 tonebarextralowmod;02E9 tonebarhighmod;02E6 tonebarlowmod;02E8 tonebarmidmod;02E7 tonefive;01BD tonesix;0185 tonetwo;01A8 tonos;0384 tonsquare;3327 topatakthai;0E0F tortoiseshellbracketleft;3014 tortoiseshellbracketleftsmall;FE5D tortoiseshellbracketleftvertical;FE39 tortoiseshellbracketright;3015 tortoiseshellbracketrightsmall;FE5E tortoiseshellbracketrightvertical;FE3A totaothai;0E15 tpalatalhook;01AB tparen;24AF trademark;2122 trademarksans;F8EA trademarkserif;F6DB tretroflexhook;0288 triagdn;25BC triaglf;25C4 triagrt;25BA triagup;25B2 ts;02A6 tsadi;05E6 tsadidagesh;FB46 tsadidageshhebrew;FB46 tsadihebrew;05E6 tsecyrillic;0446 tsere;05B5 tsere12;05B5 tsere1e;05B5 tsere2b;05B5 tserehebrew;05B5 tserenarrowhebrew;05B5 tserequarterhebrew;05B5 tserewidehebrew;05B5 tshecyrillic;045B tsuperior;F6F3 ttabengali;099F ttadeva;091F ttagujarati;0A9F ttagurmukhi;0A1F tteharabic;0679 ttehfinalarabic;FB67 ttehinitialarabic;FB68 ttehmedialarabic;FB69 tthabengali;09A0 tthadeva;0920 tthagujarati;0AA0 tthagurmukhi;0A20 tturned;0287 tuhiragana;3064 tukatakana;30C4 tukatakanahalfwidth;FF82 tusmallhiragana;3063 tusmallkatakana;30C3 tusmallkatakanahalfwidth;FF6F twelvecircle;246B twelveparen;247F twelveperiod;2493 twelveroman;217B twentycircle;2473 twentyhangzhou;5344 twentyparen;2487 twentyperiod;249B two;0032 twoarabic;0662 twobengali;09E8 twocircle;2461 twocircleinversesansserif;278B twodeva;0968 twodotenleader;2025 twodotleader;2025 twodotleadervertical;FE30 twogujarati;0AE8 twogurmukhi;0A68 twohackarabic;0662 twohangzhou;3022 twoideographicparen;3221 twoinferior;2082 twomonospace;FF12 twonumeratorbengali;09F5 twooldstyle;F732 twoparen;2475 twoperiod;2489 twopersian;06F2 tworoman;2171 twostroke;01BB twosuperior;00B2 twothai;0E52 twothirds;2154 u;0075 uacute;00FA ubar;0289 ubengali;0989 ubopomofo;3128 ubreve;016D ucaron;01D4 ucircle;24E4 ucircumflex;00FB ucircumflexbelow;1E77 ucyrillic;0443 udattadeva;0951 udblacute;0171 udblgrave;0215 udeva;0909 udieresis;00FC udieresisacute;01D8 udieresisbelow;1E73 udieresiscaron;01DA udieresiscyrillic;04F1 udieresisgrave;01DC udieresismacron;01D6 udotbelow;1EE5 ugrave;00F9 ugujarati;0A89 ugurmukhi;0A09 uhiragana;3046 uhookabove;1EE7 uhorn;01B0 uhornacute;1EE9 uhorndotbelow;1EF1 uhorngrave;1EEB uhornhookabove;1EED uhorntilde;1EEF uhungarumlaut;0171 uhungarumlautcyrillic;04F3 uinvertedbreve;0217 ukatakana;30A6 ukatakanahalfwidth;FF73 ukcyrillic;0479 ukorean;315C umacron;016B umacroncyrillic;04EF umacrondieresis;1E7B umatragurmukhi;0A41 umonospace;FF55 underscore;005F underscoredbl;2017 underscoremonospace;FF3F underscorevertical;FE33 underscorewavy;FE4F union;222A universal;2200 uogonek;0173 uparen;24B0 upblock;2580 upperdothebrew;05C4 upsilon;03C5 upsilondieresis;03CB upsilondieresistonos;03B0 upsilonlatin;028A upsilontonos;03CD uptackbelowcmb;031D uptackmod;02D4 uragurmukhi;0A73 uring;016F ushortcyrillic;045E usmallhiragana;3045 usmallkatakana;30A5 usmallkatakanahalfwidth;FF69 ustraightcyrillic;04AF ustraightstrokecyrillic;04B1 utilde;0169 utildeacute;1E79 utildebelow;1E75 uubengali;098A uudeva;090A uugujarati;0A8A uugurmukhi;0A0A uumatragurmukhi;0A42 uuvowelsignbengali;09C2 uuvowelsigndeva;0942 uuvowelsigngujarati;0AC2 uvowelsignbengali;09C1 uvowelsigndeva;0941 uvowelsigngujarati;0AC1 v;0076 vadeva;0935 vagujarati;0AB5 vagurmukhi;0A35 vakatakana;30F7 vav;05D5 vavdagesh;FB35 vavdagesh65;FB35 vavdageshhebrew;FB35 vavhebrew;05D5 vavholam;FB4B vavholamhebrew;FB4B vavvavhebrew;05F0 vavyodhebrew;05F1 vcircle;24E5 vdotbelow;1E7F vecyrillic;0432 veharabic;06A4 vehfinalarabic;FB6B vehinitialarabic;FB6C vehmedialarabic;FB6D vekatakana;30F9 venus;2640 verticalbar;007C verticallineabovecmb;030D verticallinebelowcmb;0329 verticallinelowmod;02CC verticallinemod;02C8 vewarmenian;057E vhook;028B vikatakana;30F8 viramabengali;09CD viramadeva;094D viramagujarati;0ACD visargabengali;0983 visargadeva;0903 visargagujarati;0A83 vmonospace;FF56 voarmenian;0578 voicediterationhiragana;309E voicediterationkatakana;30FE voicedmarkkana;309B voicedmarkkanahalfwidth;FF9E vokatakana;30FA vparen;24B1 vtilde;1E7D vturned;028C vuhiragana;3094 vukatakana;30F4 w;0077 wacute;1E83 waekorean;3159 wahiragana;308F wakatakana;30EF wakatakanahalfwidth;FF9C wakorean;3158 wasmallhiragana;308E wasmallkatakana;30EE wattosquare;3357 wavedash;301C wavyunderscorevertical;FE34 wawarabic;0648 wawfinalarabic;FEEE wawhamzaabovearabic;0624 wawhamzaabovefinalarabic;FE86 wbsquare;33DD wcircle;24E6 wcircumflex;0175 wdieresis;1E85 wdotaccent;1E87 wdotbelow;1E89 wehiragana;3091 weierstrass;2118 wekatakana;30F1 wekorean;315E weokorean;315D wgrave;1E81 whitebullet;25E6 whitecircle;25CB whitecircleinverse;25D9 whitecornerbracketleft;300E whitecornerbracketleftvertical;FE43 whitecornerbracketright;300F whitecornerbracketrightvertical;FE44 whitediamond;25C7 whitediamondcontainingblacksmalldiamond;25C8 whitedownpointingsmalltriangle;25BF whitedownpointingtriangle;25BD whiteleftpointingsmalltriangle;25C3 whiteleftpointingtriangle;25C1 whitelenticularbracketleft;3016 whitelenticularbracketright;3017 whiterightpointingsmalltriangle;25B9 whiterightpointingtriangle;25B7 whitesmallsquare;25AB whitesmilingface;263A whitesquare;25A1 whitestar;2606 whitetelephone;260F whitetortoiseshellbracketleft;3018 whitetortoiseshellbracketright;3019 whiteuppointingsmalltriangle;25B5 whiteuppointingtriangle;25B3 wihiragana;3090 wikatakana;30F0 wikorean;315F wmonospace;FF57 wohiragana;3092 wokatakana;30F2 wokatakanahalfwidth;FF66 won;20A9 wonmonospace;FFE6 wowaenthai;0E27 wparen;24B2 wring;1E98 wsuperior;02B7 wturned;028D wynn;01BF x;0078 xabovecmb;033D xbopomofo;3112 xcircle;24E7 xdieresis;1E8D xdotaccent;1E8B xeharmenian;056D xi;03BE xmonospace;FF58 xparen;24B3 xsuperior;02E3 y;0079 yaadosquare;334E yabengali;09AF yacute;00FD yadeva;092F yaekorean;3152 yagujarati;0AAF yagurmukhi;0A2F yahiragana;3084 yakatakana;30E4 yakatakanahalfwidth;FF94 yakorean;3151 yamakkanthai;0E4E yasmallhiragana;3083 yasmallkatakana;30E3 yasmallkatakanahalfwidth;FF6C yatcyrillic;0463 ycircle;24E8 ycircumflex;0177 ydieresis;00FF ydotaccent;1E8F ydotbelow;1EF5 yeharabic;064A yehbarreearabic;06D2 yehbarreefinalarabic;FBAF yehfinalarabic;FEF2 yehhamzaabovearabic;0626 yehhamzaabovefinalarabic;FE8A yehhamzaaboveinitialarabic;FE8B yehhamzaabovemedialarabic;FE8C yehinitialarabic;FEF3 yehmedialarabic;FEF4 yehmeeminitialarabic;FCDD yehmeemisolatedarabic;FC58 yehnoonfinalarabic;FC94 yehthreedotsbelowarabic;06D1 yekorean;3156 yen;00A5 yenmonospace;FFE5 yeokorean;3155 yeorinhieuhkorean;3186 yerahbenyomohebrew;05AA yerahbenyomolefthebrew;05AA yericyrillic;044B yerudieresiscyrillic;04F9 yesieungkorean;3181 yesieungpansioskorean;3183 yesieungsioskorean;3182 yetivhebrew;059A ygrave;1EF3 yhook;01B4 yhookabove;1EF7 yiarmenian;0575 yicyrillic;0457 yikorean;3162 yinyang;262F yiwnarmenian;0582 ymonospace;FF59 yod;05D9 yoddagesh;FB39 yoddageshhebrew;FB39 yodhebrew;05D9 yodyodhebrew;05F2 yodyodpatahhebrew;FB1F yohiragana;3088 yoikorean;3189 yokatakana;30E8 yokatakanahalfwidth;FF96 yokorean;315B yosmallhiragana;3087 yosmallkatakana;30E7 yosmallkatakanahalfwidth;FF6E yotgreek;03F3 yoyaekorean;3188 yoyakorean;3187 yoyakthai;0E22 yoyingthai;0E0D yparen;24B4 ypogegrammeni;037A ypogegrammenigreekcmb;0345 yr;01A6 yring;1E99 ysuperior;02B8 ytilde;1EF9 yturned;028E yuhiragana;3086 yuikorean;318C yukatakana;30E6 yukatakanahalfwidth;FF95 yukorean;3160 yusbigcyrillic;046B yusbigiotifiedcyrillic;046D yuslittlecyrillic;0467 yuslittleiotifiedcyrillic;0469 yusmallhiragana;3085 yusmallkatakana;30E5 yusmallkatakanahalfwidth;FF6D yuyekorean;318B yuyeokorean;318A yyabengali;09DF yyadeva;095F z;007A zaarmenian;0566 zacute;017A zadeva;095B zagurmukhi;0A5B zaharabic;0638 zahfinalarabic;FEC6 zahinitialarabic;FEC7 zahiragana;3056 zahmedialarabic;FEC8 zainarabic;0632 zainfinalarabic;FEB0 zakatakana;30B6 zaqefgadolhebrew;0595 zaqefqatanhebrew;0594 zarqahebrew;0598 zayin;05D6 zayindagesh;FB36 zayindageshhebrew;FB36 zayinhebrew;05D6 zbopomofo;3117 zcaron;017E zcircle;24E9 zcircumflex;1E91 zcurl;0291 zdot;017C zdotaccent;017C zdotbelow;1E93 zecyrillic;0437 zedescendercyrillic;0499 zedieresiscyrillic;04DF zehiragana;305C zekatakana;30BC zero;0030 zeroarabic;0660 zerobengali;09E6 zerodeva;0966 zerogujarati;0AE6 zerogurmukhi;0A66 zerohackarabic;0660 zeroinferior;2080 zeromonospace;FF10 zerooldstyle;F730 zeropersian;06F0 zerosuperior;2070 zerothai;0E50 zerowidthjoiner;FEFF zerowidthnonjoiner;200C zerowidthspace;200B zeta;03B6 zhbopomofo;3113 zhearmenian;056A zhebrevecyrillic;04C2 zhecyrillic;0436 zhedescendercyrillic;0497 zhedieresiscyrillic;04DD zihiragana;3058 zikatakana;30B8 zinorhebrew;05AE zlinebelow;1E95 zmonospace;FF5A zohiragana;305E zokatakana;30BE zparen;24B5 zretroflexhook;0290 zstroke;01B6 zuhiragana;305A zukatakana;30BA #END lcdf-typetools-2.108/otfinfo/0000755000175000017500000000000013423377073013152 500000000000000lcdf-typetools-2.108/otfinfo/otfinfo.cc0000644000175000017500000005453013423375330015046 00000000000000/* otfinfo.cc -- driver for reporting information about OpenType fonts * * Copyright (c) 2003-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_UNISTD_H # include #endif #if defined(_MSDOS) || defined(_WIN32) # include # include #endif using namespace Efont; #define VERSION_OPT 301 #define HELP_OPT 302 #define QUIET_OPT 303 #define VERBOSE_OPT 304 #define SCRIPT_OPT 305 #define QUERY_SCRIPTS_OPT 320 #define QUERY_FEATURES_OPT 321 #define QUERY_OPTICAL_SIZE_OPT 322 #define QUERY_POSTSCRIPT_NAME_OPT 323 #define QUERY_GLYPHS_OPT 324 #define QUERY_FVERSION_OPT 325 #define TABLES_OPT 326 #define QUERY_FAMILY_OPT 327 #define INFO_OPT 328 #define DUMP_TABLE_OPT 329 #define QUERY_UNICODE_OPT 330 const Clp_Option options[] = { { "script", 0, SCRIPT_OPT, Clp_ValString, 0 }, { "quiet", 'q', QUIET_OPT, 0, Clp_Negate }, { "verbose", 'V', VERBOSE_OPT, 0, Clp_Negate }, { "features", 'f', QUERY_FEATURES_OPT, 0, 0 }, { "scripts", 's', QUERY_SCRIPTS_OPT, 0, 0 }, { "size", 0, QUERY_OPTICAL_SIZE_OPT, 0, 0 }, { "optical-size", 'z', QUERY_OPTICAL_SIZE_OPT, 0, 0 }, { "postscript-name", 'p', QUERY_POSTSCRIPT_NAME_OPT, 0, 0 }, { "family", 'a', QUERY_FAMILY_OPT, 0, 0 }, { "font-version", 'v', QUERY_FVERSION_OPT, 0, 0 }, { "info", 'i', INFO_OPT, 0, 0 }, { "glyphs", 'g', QUERY_GLYPHS_OPT, 0, 0 }, { "tables", 't', TABLES_OPT, 0, 0 }, { "dump-table", 'T', DUMP_TABLE_OPT, Clp_ValString, 0 }, { "unicode", 'u', QUERY_UNICODE_OPT, 0, 0 }, { "help", 'h', HELP_OPT, 0, 0 }, { "version", 0, VERSION_OPT, 0, 0 }, }; static const char *program_name; static Efont::OpenType::Tag script, langsys; bool verbose = false; bool quiet = false; void usage_error(ErrorHandler *errh, const char *error_message, ...) { va_list val; va_start(val, error_message); if (!error_message) errh->message("Usage: %s [OPTION]... FONT", program_name); else errh->xmessage(ErrorHandler::e_error, error_message, val); errh->message("Type %s --help for more information.", program_name); exit(1); } void usage() { FileErrorHandler uerrh(stdout); uerrh.message("\ % reports information about an OpenType font to standard output.\n\ Options specify what information to print.\n\ \n\ Usage: %s [-sfzpg | OPTIONS] [OTFFILES...]\n\n", program_name); uerrh.message("\ Query options:\n\ -s, --scripts Report font%,s supported scripts.\n\ -f, --features Report font%,s GSUB/GPOS features.\n\ -z, --optical-size Report font%,s optical size information.\n\ -p, --postscript-name Report font%,s PostScript name.\n\ -a, --family Report font%,s family name.\n\ -v, --font-version Report font%,s version information.\n\ -i, --info Report font%,s names and designer/vendor info.\n\ -g, --glyphs Report font%,s glyph names.\n\ -t, --tables Report font%,s OpenType tables.\n\ -T, --dump-table NAME Output font%,s % table.\n\ \n\ Other options:\n\ --script=SCRIPT[.LANG] Set script used for --features [latn].\n\ -V, --verbose Print progress information to standard error.\n\ -h, --help Print this message and exit.\n\ -q, --quiet Do not generate any error messages.\n\ --version Print version number and exit.\n\ \n\ Report bugs to .\n"); } String read_file(String filename, ErrorHandler *errh, bool warning = false) { FILE *f; int f_errno = 0; if (!filename || filename == "-") { filename = ""; f = stdin; #if defined(_MSDOS) || defined(_WIN32) // Set the file mode to binary _setmode(_fileno(f), _O_BINARY); #endif } else { f = fopen(filename.c_str(), "rb"); f_errno = errno; } String error_anno = (warning ? errh->e_warning : errh->e_error) + ErrorHandler::make_landmark_anno(filename); if (!f) { errh->xmessage(error_anno, strerror(f_errno)); return String(); } StringAccum sa; int amt; do { if (char *x = sa.reserve(8192)) { amt = fread(x, 1, 8192, f); sa.adjust_length(amt); } else amt = 0; } while (amt != 0); if (!feof(f) || ferror(f)) errh->xmessage(error_anno, strerror(errno)); if (f != stdin) fclose(f); return sa.take_string(); } String printable_filename(const String &s) { if (!s || s == "-") return String::make_stable(""); else return s; } static void collect_script_descriptions(const OpenType::ScriptList &script_list, Vector &output, ErrorHandler *errh) { Vector script, langsys; script_list.language_systems(script, langsys, errh); for (int i = 0; i < script.size(); i++) { String what = script[i].text(); const char *s = script[i].script_description(); String where = (s ? s : ""); if (!langsys[i].null()) { what += String(".") + langsys[i].text(); s = langsys[i].language_description(); where += String("/") + (s ? s : ""); } if (what.length() < 8) output.push_back(what + String("\t\t") + where); else output.push_back(what + String("\t") + where); } } static void do_query_scripts(const OpenType::Font &otf, ErrorHandler *errh, ErrorHandler *result_errh) { Vector results; if (String gsub_table = otf.table("GSUB")) { OpenType::Gsub gsub(gsub_table, &otf, errh); collect_script_descriptions(gsub.script_list(), results, errh); } if (String gpos_table = otf.table("GPOS")) { OpenType::Gpos gpos(gpos_table, errh); collect_script_descriptions(gpos.script_list(), results, errh); } if (results.size()) { std::sort(results.begin(), results.end()); String *unique_result = std::unique(results.begin(), results.end()); for (String *sp = results.begin(); sp < unique_result; sp++) result_errh->message("%s", sp->c_str()); } } static void collect_feature_descriptions(const OpenType::ScriptList &script_list, const OpenType::FeatureList &feature_list, Vector &output, ErrorHandler *errh) { int required_fid; Vector fids; // collect features applying to this script script_list.features(script, langsys, required_fid, fids, errh); for (int i = -1; i < fids.size(); i++) { int fid = (i < 0 ? required_fid : fids[i]); if (fid >= 0) { OpenType::Tag tag = feature_list.tag(fid); const char *s = tag.feature_description(); output.push_back(tag.text() + String("\t") + (s ? s : "")); } } } static void do_query_features(const OpenType::Font &otf, ErrorHandler *errh, ErrorHandler *result_errh) { Vector results; if (String gsub_table = otf.table("GSUB")) { OpenType::Gsub gsub(gsub_table, &otf, errh); collect_feature_descriptions(gsub.script_list(), gsub.feature_list(), results, errh); } if (String gpos_table = otf.table("GPOS")) { OpenType::Gpos gpos(gpos_table, errh); collect_feature_descriptions(gpos.script_list(), gpos.feature_list(), results, errh); } if (results.size()) { std::sort(results.begin(), results.end()); String *unique_result = std::unique(results.begin(), results.end()); for (String *sp = results.begin(); sp < unique_result; sp++) result_errh->message("%s", sp->c_str()); } } static bool do_query_optical_size_size(const OpenType::Font &otf, ErrorHandler *errh, ErrorHandler *result_errh) { int before_nerrors = errh->nerrors(); try { String gpos_table = otf.table("GPOS"); if (!gpos_table) return false; OpenType::Gpos gpos(gpos_table, errh); OpenType::Name name(otf.table("name"), errh); // extract 'size' feature int required_fid; Vector fids; gpos.script_list().features(script, langsys, required_fid, fids, errh); int size_fid = gpos.feature_list().find(OpenType::Tag("size"), fids); if (size_fid < 0) return false; // old Adobe fonts implement an old, incorrect idea // of what the FeatureParams offset means. OpenType::Data size_data = gpos.feature_list().size_params(size_fid, name, errh); if (!size_data.length()) return false; StringAccum sa; sa << "design size " << (size_data.u16(0) / 10.) << " pt"; if (size_data.u16(2) != 0) { sa << ", size range (" << (size_data.u16(6) / 10.) << " pt, " << (size_data.u16(8) / 10.) << " pt], " << "subfamily ID " << size_data.u16(2); if (String n = name.english_name(size_data.u16(4))) sa << ", subfamily name " << n; } result_errh->message("%s", sa.c_str()); return true; } catch (OpenType::Error) { return errh->nerrors() != before_nerrors; } } static void do_query_optical_size(const OpenType::Font &otf, ErrorHandler *errh, ErrorHandler *result_errh) { int before_nerrors = errh->nerrors(); try { if (do_query_optical_size_size(otf, errh, result_errh)) return; String os2_table = otf.table("OS/2"); if (!os2_table) throw OpenType::Error(); OpenType::Os2 os2(os2_table, errh); if (!os2.ok() || !os2.has_optical_point_size()) throw OpenType::Error(); StringAccum sa; sa << "size range [" << os2.lower_optical_point_size() << ", " << os2.upper_optical_point_size() << ")"; result_errh->message("%s", sa.c_str()); } catch (OpenType::Error) { if (errh->nerrors() == before_nerrors) result_errh->message("no optical size information"); } } static void do_query_family_name(const OpenType::Font &otf, ErrorHandler *errh, ErrorHandler *result_errh) { int before_nerrors = errh->nerrors(); String family_name = "no family name information"; if (String name_table = otf.table("name")) { OpenType::Name name(name_table, errh); if (name.ok()) family_name = name.english_name(OpenType::Name::N_FAMILY); } if (errh->nerrors() == before_nerrors) result_errh->message("%s", family_name.c_str()); } static void do_query_postscript_name(const OpenType::Font &otf, ErrorHandler *errh, ErrorHandler *result_errh) { int before_nerrors = errh->nerrors(); String postscript_name = "no PostScript name information"; if (String name_table = otf.table("name")) { OpenType::Name name(name_table, errh); if (name.ok()) postscript_name = name.english_name(OpenType::Name::N_POSTSCRIPT); } if (errh->nerrors() == before_nerrors) result_errh->message("%s", postscript_name.c_str()); } static void do_query_font_version(const OpenType::Font &otf, ErrorHandler *errh, ErrorHandler *result_errh) { int before_nerrors = errh->nerrors(); String version = "no version information"; if (String name_table = otf.table("name")) { OpenType::Name name(name_table, errh); if (name.ok()) version = name.english_name(OpenType::Name::N_VERSION); } if (errh->nerrors() == before_nerrors) result_errh->message("%s", version.c_str()); } static void do_info(const OpenType::Font &otf, ErrorHandler *errh, ErrorHandler *result_errh) { int before_nerrors = errh->nerrors(); StringAccum sa; if (String name_table = otf.table("name")) { OpenType::Name name(name_table, errh); if (name.ok()) { if (String s = name.english_name(OpenType::Name::N_FAMILY)) sa << "Family: " << s << "\n"; if (String s = name.english_name(OpenType::Name::N_SUBFAMILY)) sa << "Subfamily: " << s << "\n"; if (String s = name.english_name(OpenType::Name::N_FULLNAME)) sa << "Full name: " << s << "\n"; if (String s = name.english_name(OpenType::Name::N_POSTSCRIPT)) sa << "PostScript name: " << s << "\n"; if (String s = name.english_name(OpenType::Name::N_POSTSCRIPT_CID)) sa << "PostScript CID name: " << s << "\n"; if (String s = name.english_name(OpenType::Name::N_PREF_FAMILY)) sa << "Preferred family: " << s << "\n"; if (String s = name.english_name(OpenType::Name::N_PREF_SUBFAMILY)) sa << "Preferred subfamily: " << s << "\n"; if (String s = name.english_name(OpenType::Name::N_MAC_COMPAT_FULLNAME)) sa << "Mac font menu name: " << s << "\n"; if (String s = name.english_name(OpenType::Name::N_VERSION)) sa << "Version: " << s << "\n"; if (String s = name.english_name(OpenType::Name::N_UNIQUEID)) sa << "Unique ID: " << s << "\n"; if (String s = name.english_name(OpenType::Name::N_DESCRIPTION)) sa << "Description: " << s << "\n"; if (String s = name.english_name(OpenType::Name::N_DESIGNER)) sa << "Designer: " << s << "\n"; if (String s = name.english_name(OpenType::Name::N_DESIGNER_URL)) sa << "Designer URL: " << s << "\n"; if (String s = name.english_name(OpenType::Name::N_MANUFACTURER)) sa << "Manufacturer: " << s << "\n"; if (String s = name.english_name(OpenType::Name::N_VENDOR_URL)) sa << "Vendor URL: " << s << "\n"; if (String s = name.english_name(OpenType::Name::N_TRADEMARK)) sa << "Trademark: " << s << "\n"; if (String s = name.english_name(OpenType::Name::N_COPYRIGHT)) sa << "Copyright: " << s << "\n"; if (String s = name.english_name(OpenType::Name::N_LICENSE_URL)) sa << "License URL: " << s << "\n"; if (String s = name.english_name(OpenType::Name::N_LICENSE_DESCRIPTION)) sa << "License Description: " << s << "\n"; if (String s = name.english_name(OpenType::Name::N_SAMPLE_TEXT)) sa << "Sample text: " << s << "\n"; } } if (String os2_table = otf.table("OS/2")) { OpenType::Os2 os2(os2_table, errh); if (os2.ok()) { if (String s = os2.vendor_id()) { while (s.length() && (s.back() == ' ' || s.back() == 0)) s = s.substring(s.begin(), s.end() - 1); if (s) sa << "Vendor ID: " << s << "\n"; } } } if (sa || errh->nerrors() == before_nerrors) result_errh->message("%s", (sa ? sa.c_str() : "no information")); } static void do_query_glyphs_cff(const OpenType::Font& otf, ErrorHandler* errh, Vector& glyph_names) { try { // get font Cff cff(otf.table("CFF"), otf.units_per_em(), errh); if (!cff.ok()) return; Cff::FontParent *fp = cff.font(PermString(), errh); if (!fp || !fp->ok()) return; Cff::Font *font = dynamic_cast(fp); if (!font) { errh->error("CID-keyed fonts not supported"); return; } // save glyph names font->glyph_names(glyph_names); } catch (OpenType::Error) { } } static void do_query_glyphs_post(const OpenType::Font& otf, ErrorHandler* errh, Vector& glyph_names) { try { // get font OpenType::Post post(otf.table("post"), errh); if (!post.ok()) return; // save glyph names post.glyph_names(glyph_names); } catch (OpenType::Error) { } } static void do_query_glyphs(const OpenType::Font &otf, ErrorHandler *errh, ErrorHandler *result_errh) { int before_nerrors = errh->nerrors(); Vector glyph_names; if (otf.table("CFF")) do_query_glyphs_cff(otf, errh, glyph_names); else if (otf.table("post")) do_query_glyphs_post(otf, errh, glyph_names); for (PermString* s = glyph_names.begin(); s != glyph_names.end(); ++s) result_errh->message("%s", s->c_str()); if (glyph_names.empty() && errh->nerrors() == before_nerrors) errh->message("no glyph name information"); } static void do_query_unicode(const OpenType::Font& otf, ErrorHandler* errh, ErrorHandler* result_errh) { Vector glyph_names; if (otf.table("CFF")) do_query_glyphs_cff(otf, errh, glyph_names); else if (otf.table("post")) do_query_glyphs_post(otf, errh, glyph_names); try { OpenType::Cmap cmap(otf.table("cmap"), errh); if (!cmap.ok()) throw OpenType::Error(); Vector > u2g; cmap.unmap_all(u2g); std::sort(u2g.begin(), u2g.end()); for (std::pair* it = u2g.begin(); it != u2g.end(); ++it) { char name[10]; if (it->first < 0x10000) sprintf(name, "uni%04X", it->first); else sprintf(name, "u%X", it->first); if (it->second < glyph_names.size()) result_errh->message("%s %d %s\n", name, it->second, glyph_names[it->second].c_str()); else result_errh->message("%s %d\n", name, it->second); } } catch (OpenType::Error) { } } static void do_tables(const OpenType::Font &otf, ErrorHandler *errh, ErrorHandler *result_errh) { int before_nerrors = errh->nerrors(); try { int n = otf.ntables(); for (int i = 0; i < n; i++) if (OpenType::Tag tag = otf.table_tag(i)) { String s = otf.table(tag); result_errh->message("%7u %s\n", s.length(), tag.text().c_str()); } } catch (OpenType::Error) { if (errh->nerrors() == before_nerrors) result_errh->message("corrupted tables"); } } static void do_dump_table(const OpenType::Font &otf, OpenType::Tag tag, ErrorHandler *errh) { int before_nerrors = errh->nerrors(); try { if (otf.has_table(tag)) { String s = otf.table(tag); int written = fwrite(s.data(), 1, s.length(), stdout); if (written != s.length()) errh->error("%s", strerror(errno)); } else errh->message("no %<%s%> table", tag.text().c_str()); } catch (OpenType::Error) { if (errh->nerrors() == before_nerrors) errh->message("corrupted tables"); } } int main(int argc, char *argv[]) { Clp_Parser *clp = Clp_NewParser(argc, (const char * const *)argv, sizeof(options) / sizeof(options[0]), options); program_name = Clp_ProgramName(clp); ErrorHandler *errh = ErrorHandler::static_initialize(new FileErrorHandler(stderr, String(program_name) + ": ")); Vector input_files; OpenType::Tag dump_table; int query = 0; while (1) { int opt = Clp_Next(clp); switch (opt) { case SCRIPT_OPT: { if (!script.null()) usage_error(errh, "--script already specified"); String arg = clp->vstr; int period = arg.find_left('.'); OpenType::Tag scr(period <= 0 ? arg : arg.substring(0, period)); if (scr.valid() && period > 0) { OpenType::Tag lang(arg.substring(period + 1)); if (lang.valid()) { script = scr; langsys = lang; } else usage_error(errh, "bad language tag"); } else if (scr.valid()) script = scr; else usage_error(errh, "bad script tag"); break; } case QUERY_SCRIPTS_OPT: case QUERY_FEATURES_OPT: case QUERY_OPTICAL_SIZE_OPT: case QUERY_POSTSCRIPT_NAME_OPT: case QUERY_GLYPHS_OPT: case QUERY_FAMILY_OPT: case QUERY_FVERSION_OPT: case QUERY_UNICODE_OPT: case TABLES_OPT: case INFO_OPT: if (query) usage_error(errh, "supply exactly one query type option"); query = opt; break; case DUMP_TABLE_OPT: if (query) usage_error(errh, "supply exactly one query type option"); if (!(dump_table = OpenType::Tag(clp->vstr))) usage_error(errh, "bad table name"); query = opt; break; case QUIET_OPT: if (clp->negated) errh = ErrorHandler::default_handler(); else errh = new SilentErrorHandler; break; case VERBOSE_OPT: verbose = !clp->negated; break; case VERSION_OPT: printf("otfinfo (LCDF typetools) %s\n", VERSION); printf("Copyright (C) 2003-2019 Eddie Kohler\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); exit(0); break; case HELP_OPT: usage(); exit(0); break; case Clp_NotOption: input_files.push_back(clp->vstr); break; case Clp_Done: goto done; case Clp_BadOption: usage_error(errh, 0); break; default: break; } } done: if (!query) usage_error(errh, "supply exactly one query option"); if (!input_files.size()) input_files.push_back("-"); if (script.null()) script = Efont::OpenType::Tag("latn"); FileErrorHandler stdout_errh(stdout); for (const char **input_filep = input_files.begin(); input_filep != input_files.end(); input_filep++) { int before_nerrors = errh->nerrors(); String font_data = read_file(*input_filep, errh); if (errh->nerrors() != before_nerrors) continue; String input_file = printable_filename(*input_filep); LandmarkErrorHandler cerrh(errh, input_file); OpenType::Font otf(font_data, &cerrh); if (!otf.ok()) continue; PrefixErrorHandler stdout_cerrh(&stdout_errh, input_file + ":"); ErrorHandler *result_errh = (input_files.size() > 1 ? static_cast(&stdout_cerrh) : static_cast(&stdout_errh)); if (query == QUERY_SCRIPTS_OPT) do_query_scripts(otf, &cerrh, result_errh); else if (query == QUERY_FEATURES_OPT) do_query_features(otf, &cerrh, result_errh); else if (query == QUERY_OPTICAL_SIZE_OPT) do_query_optical_size(otf, &cerrh, result_errh); else if (query == QUERY_POSTSCRIPT_NAME_OPT) do_query_postscript_name(otf, &cerrh, result_errh); else if (query == QUERY_GLYPHS_OPT) do_query_glyphs(otf, &cerrh, result_errh); else if (query == QUERY_UNICODE_OPT) do_query_unicode(otf, &cerrh, result_errh); else if (query == QUERY_FAMILY_OPT) do_query_family_name(otf, &cerrh, result_errh); else if (query == QUERY_FVERSION_OPT) do_query_font_version(otf, &cerrh, result_errh); else if (query == TABLES_OPT) do_tables(otf, &cerrh, result_errh); else if (query == DUMP_TABLE_OPT) do_dump_table(otf, dump_table, &cerrh); else if (query == INFO_OPT) do_info(otf, &cerrh, result_errh); } Clp_DeleteParser(clp); return (errh->nerrors() == 0 ? 0 : 1); } lcdf-typetools-2.108/otfinfo/otfinfo.10000644000175000017500000001033713423376706014626 00000000000000'\"t .ds V 2.108 .de M .BR "\\$1" "(\\$2)\\$3" .. .de Sp .if n .sp .if t .sp 0.4 .. .TH OTFINFO 1 "LCDF Typetools" "Version \*V" .SH NAME otfinfo \- report information about OpenType fonts .SH SYNOPSIS .B otfinfo \%[\fB-sfzpvag\fR] \%[\fIFILE...\fR] ' .SH DESCRIPTION .BR Otfinfo reports information about the named OpenType font .IR FILE s (or standard input, if no .IR FILE s are given). Results are printed to standard output. Each line is prefaced with the relevant .I FILE if more than one .I FILE was supplied. ' .SH OPTIONS With long options, you need type only as many characters as will make the option unique. .SS Query options .PD 0 .PD 0 .TP 5 .BR \-s ", " \-\-scripts Print supported scripts and language systems. The scripts are printed one per line, with human-readable descriptions; for example: .nf cyrl Cyrillic grek Greek latn Latin latn.TUR Latin/Turkish .fi ' .Sp .TP 5 .BR \-f ", " \-\-features Print GSUB and GPOS features supported by the selected script (see the .B \-\-script option below). The scripts are printed one per line, with human-readable descriptions; for example: .nf aalt Access All Alternates c2sc Small Capitals From Capitals case Case-Sensitive Forms cpsp Capital Spacing \&... zero Slashed Zero .fi ' .Sp .TP 5 .BR \-z ", " \-\-optical\-size Print optical size information. For example: .nf design size 11 pt, size range (8.4 pt, 13 pt], subfamily ID 11, subfamily name Semibold Italic .fi ' .Sp .TP 5 .BR \-p ", " \-\-postscript\-name Print each font's PostScript name. For example: .nf MinionPro-SemiboldItCapt .fi ' .Sp .TP 5 .BR \-a ", " \-\-family Print each font's family name. For example: .nf Minion Pro .fi ' .Sp .TP 5 .BR \-v ", " \-\-font\-version Print font version information, if available. For example: .nf OTF 1.013;PS 001.000;Core 1.0.27;makeotf.lib(1.11) .fi ' .Sp .TP 5 .BR \-i ", " \-\-info Print each font's name, version, designer, vendor, copyright, and license information. For example: .nf Family: Minion Pro Subfamily: Regular Full name: Minion Pro PostScript name: MinionPro-Regular Version: OTF 1.011;PS 001.000;Core 1.0.27;makeotf.lib1.3.1 Unique ID: 1.011;ADBE;MinionPro-Regular Designer: Robert Slimbach Vendor URL: http://www.adobe.com/type/ Trademark: Minion is either a registered trademark or a trademark of Adobe Systems Incorporated in the United States and/or other countries. Copyright: \(co 2000 Adobe Systems Incorporated. All Rights Reserved. U.S. Patent Des. 337,604. Other patents pending. License URL: http://www.adobe.com/type/legal.html .fi ' .Sp .TP 5 .BR \-g ", " \-\-glyphs Print the name of every glyph in each font, one per line. For example: .nf \&.notdef space exclam \&... ncommaaccent.end lje.alt .fi ' .Sp .TP 5 .BR \-u ", " \-\-unicode Print each Unicode code point supported by the font, followed by the glyph number representing that code point (and, if present, the name of the corresponding glyph). .Sp .TP 5 .BR \-t ", " \-\-tables Print the size and name of every OpenType table in the font. For example: .nf 52 BASE 87723 CFF 4940 DSIG 21366 GPOS \&... .fi ' .Sp .TP 5 .BR \-T " \fItable\fR, " \-\-dump\-table= \fItable\fR Print the contents of the font's OpenType table \fItable\fR. ' .PD ' ' .SS Miscellaneous options ' .PD 0 .TP 5 .BI \-\-script= "script\fR[.\fIlang\fR]" Select the script system .I script and language system .IR lang used to look up features by .BR \-\-features . Examples include "latn" (Latin script), "grek" (Greek script), and "yi.YIC" (Yi script with classic characters). If .I lang is not specified, otfinfo will use the default language system for that script. Defaults to "latn". ' .Sp .TP 5 .BR \-V ", " \-\-verbose Write progress messages to standard error. ' .Sp .TP 5 .BR \-q ", " \-\-quiet Do not generate any error messages. ' .Sp .TP 5 .BR \-h ", " \-\-help Print usage information and exit. ' .Sp .TP 5 .BR \-\-version Print the version number and some short non-warranty information and exit. .PD ' .SH "SEE ALSO" .LP .M otftotfm 1 .LP .IR "OpenType Specification" , Version 1.4 ' .SH AUTHOR Eddie Kohler (ekohler@gmail.com) lcdf-typetools-2.108/otfinfo/Makefile.in0000644000175000017500000005101413423376574015145 00000000000000# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : bin_PROGRAMS = otfinfo$(EXEEXT) subdir = otfinfo ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/lcdf-typetools.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/autoconf.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" PROGRAMS = $(bin_PROGRAMS) am_otfinfo_OBJECTS = otfinfo.$(OBJEXT) otfinfo_OBJECTS = $(am_otfinfo_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(otfinfo_SOURCES) DIST_SOURCES = $(otfinfo_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KPATHSEA_DEPEND = @KPATHSEA_DEPEND@ KPATHSEA_INCLUDES = @KPATHSEA_INCLUDES@ KPATHSEA_LIBS = @KPATHSEA_LIBS@ KPATHSEA_RULE = @KPATHSEA_RULE@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SELECTED_SUBDIRS = @SELECTED_SUBDIRS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TEMPLATE_OBJS = @TEMPLATE_OBJS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ encdir = @encdir@ exec_prefix = @exec_prefix@ glyphlistdir = @glyphlistdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign man_MANS = otfinfo.1 otfinfo_SOURCES = \ otfinfo.cc otfinfo_LDADD = ../libefont/libefont.a ../liblcdf/liblcdf.a otfinfo_DEPENDENCIES = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_CPPFLAGS = -I$(srcdir)/../include CLEANFILES = @TEMPLATE_OBJS@ EXTRA_DIST = otfinfo.1 all: all-am .SUFFIXES: .SUFFIXES: .cc .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign otfinfo/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign otfinfo/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) otfinfo$(EXEEXT): $(otfinfo_OBJECTS) $(otfinfo_DEPENDENCIES) $(EXTRA_otfinfo_DEPENDENCIES) @rm -f otfinfo$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(otfinfo_OBJECTS) $(otfinfo_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/otfinfo.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-man uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-binPROGRAMS install-data install-data-am \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-man1 install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-binPROGRAMS uninstall-man uninstall-man1 .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lcdf-typetools-2.108/otfinfo/Makefile.am0000664000175000017500000000057612732752520015134 00000000000000## Process this file with automake to produce Makefile.in AUTOMAKE_OPTIONS = foreign bin_PROGRAMS = otfinfo man_MANS = otfinfo.1 otfinfo_SOURCES = \ otfinfo.cc otfinfo_LDADD = ../libefont/libefont.a ../liblcdf/liblcdf.a otfinfo_DEPENDENCIES = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_CPPFLAGS = -I$(srcdir)/../include CLEANFILES = @TEMPLATE_OBJS@ EXTRA_DIST = otfinfo.1 lcdf-typetools-2.108/README.md0000644000175000017500000001040013423376706012702 00000000000000LCDF Typetools ============== LCDF Typetools comprises several programs for manipulating PostScript Type 1, Type 1 Multiple Master, OpenType, and TrueType fonts. **cfftot1** translates a Compact Font Format (CFF) font, or a PostScript-flavored OpenType font, into PostScript Type 1 format. It correctly handles subroutines and hints. **mmafm** creates an AFM file (font metrics) corresponding to an instance of a Type 1 Multiple Master font. It reads the AMFM and AFM files distributed with the font. **mmpfb** creates a normal, single-master font program which looks like an instance of a Type 1 Multiple Master font. It reads the multiple master font program in PFA or PFB format. **otfinfo** reports information about OpenType and TrueType fonts, such as the OpenType features and Unicode code points they support, or the contents of their `size` optical size features. **otftotfm** creates TeX font metrics and encodings that correspond to an OpenType or TrueType font. It interprets glyph positionings, substitutions, and ligatures as far as it is able. You can say which OpenType features should be activated. **t1dotlessj** reads a Type 1 font, then creates a new Type 1 font whose only character is a dotless lower-case j matching the input font’s design. **t1lint** checks Type 1 fonts for correctness. It tests most of the requirements listed in Adobe Systems’ Black Book (“Adobe Type 1 Font Format”), and some others. **t1rawafm** creates an AFM font metrics file corresponding to a raw Type 1 font file (in PFA or PFB format). **t1reencode** reencodes a Type 1 font, replacing its internal encoding with one you specify. **t1testpage** creates PostScript test pages for a given Type 1 font. These pages show every character defined in the font. **ttftotype42** creates a Type 42 wrapper for a TrueType or TrueType-flavored OpenType font. This allows the font to be embedded in a PostScript file. Each of these programs has a manual page; `man PROGRAMNAME/PROGRAMNAME.1` for more information. See `NEWS` in this directory for changes in recent versions. The LCDF Typetools home page is: http://www.lcdf.org/type/ Installation ------------ Type `./configure`, then `make`. If `./configure` does not exist (you downloaded from Github), run `./bootstrap.sh` first. `./configure` accepts the usual options; see `INSTALL` for details. Some of the typetools programs can link with additional libraries. Otftotfm can use the Kpathsea library for integration with TeX directories; if your version of this library is in a nonstandard place, supply `./configure` with the `--with-kpathsea=PREFIX` option to find it. You can also disable individual programs by supplying `./configure` with `--disable-PROGNAME` options. See `./configure --help` for more information. Mmafm and mmpfb --------------- Run `mmafm --help` and `mmpfb --help` for a full option summary. Here are two example runs: % mmafm MyriadMM.amfm --weight=300 --width=585 > MyriadMM_300_585_.afm % mmpfb MyriadMM.pfb --weight=300 --width=585 > MyriadMM_300_585_.pfb Mmafm expects the name of an AMFM file on the command line. It also needs an AFM file for each master (these should have been distributed with the AMFM file). You can give the AFM files’ names on the command line, along with the AMFM file, or you let mmafm find the AFM files automatically. For the automatic method, you must follow one of these 2 conventions: 1. The AFM files are in the same directory as the AMFM file. They are named `FONTNAME.afm` -- `MyriadMM-LightCn.afm`, for example. 2. There is a `PSres.upr` file that lists the AFMs by font name, and the `PSRESOURCEPATH` environment variable contains the directory with that `PSres.upr` file. (`ps2pk` comes with a sample `PSres.upr` file.) Copyright and license --------------------- All source code is Copyright (c) 1997-2019 Eddie Kohler. This code is distributed under the GNU General Public License, Version 2 (and only Version 2). The GNU General Public License is available via the Web at , or in the COPYING file in this directory. Author ------ Eddie Kohler , http://www.lcdf.org/ The current version of the lcdf-typetools package is available on the Web at http://www.lcdf.org/type/ LCDF stands for Little Cambridgeport Design Factory. lcdf-typetools-2.108/Makefile.in0000644000175000017500000007456713423376574013523 00000000000000# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/lcdf-typetools.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = autoconf.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(encdir)" "$(DESTDIR)$(glyphlistdir)" DATA = $(enc_DATA) $(glyphlist_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ $(LISP)autoconf.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/autoconf.h.in \ COPYING INSTALL compile depcomp install-sh missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KPATHSEA_DEPEND = @KPATHSEA_DEPEND@ KPATHSEA_INCLUDES = @KPATHSEA_INCLUDES@ KPATHSEA_LIBS = @KPATHSEA_LIBS@ KPATHSEA_RULE = @KPATHSEA_RULE@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SELECTED_SUBDIRS = @SELECTED_SUBDIRS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TEMPLATE_OBJS = @TEMPLATE_OBJS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ encdir = @encdir@ exec_prefix = @exec_prefix@ glyphlistdir = @glyphlistdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign SUBDIRS = liblcdf libefont @SELECTED_SUBDIRS@ DIST_SUBDIRS = liblcdf libefont cfftot1 mmafm mmpfb otfinfo otftotfm \ t1dotlessj t1lint t1rawafm t1reencode t1testpage ttftotype42 EXTRA_DIST = \ ONEWS README.md NEWS.md \ lcdf-typetools.spec \ include/config.h \ include/lcdf/bezier.hh \ include/lcdf/clp.h \ include/lcdf/error.hh \ include/lcdf/filename.hh \ include/lcdf/globmatch.hh \ include/lcdf/hashcode.hh \ include/lcdf/hashmap.hh include/lcdf/hashmap.cc \ include/lcdf/inttypes.h \ include/lcdf/landmark.hh \ include/lcdf/md5.h \ include/lcdf/permstr.hh \ include/lcdf/point.hh \ include/lcdf/slurper.hh \ include/lcdf/straccum.hh \ include/lcdf/string.hh \ include/lcdf/strtonum.h \ include/lcdf/transform.hh \ include/lcdf/vector.hh include/lcdf/vector.cc \ include/efont/afm.hh \ include/efont/afmparse.hh \ include/efont/afmw.hh \ include/efont/amfm.hh \ include/efont/cff.hh \ include/efont/encoding.hh \ include/efont/findmet.hh \ include/efont/metrics.hh \ include/efont/otf.hh \ include/efont/otfcmap.hh \ include/efont/otfdata.hh \ include/efont/otfgpos.hh \ include/efont/otfgsub.hh \ include/efont/otfname.hh \ include/efont/otfos2.hh \ include/efont/otfpost.hh \ include/efont/pairop.hh \ include/efont/psres.hh \ include/efont/t1bounds.hh \ include/efont/t1cs.hh \ include/efont/t1csgen.hh \ include/efont/t1font.hh \ include/efont/t1interp.hh \ include/efont/t1item.hh \ include/efont/t1mm.hh \ include/efont/t1rw.hh \ include/efont/t1unparser.hh \ include/efont/ttfcs.hh \ include/efont/ttfhead.hh \ include/efont/ttfkern.hh \ glyphlist.txt \ texglyphlist.txt \ texglyphlist-g2u.txt \ 7t.enc glyphlist_DATA = glyphlist.txt texglyphlist.txt enc_DATA = 7t.enc all: autoconf.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): autoconf.h: stamp-h1 @test -f $@ || rm -f stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/autoconf.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status autoconf.h $(srcdir)/autoconf.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f autoconf.h stamp-h1 install-encDATA: $(enc_DATA) @$(NORMAL_INSTALL) @list='$(enc_DATA)'; test -n "$(encdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(encdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(encdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(encdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(encdir)" || exit $$?; \ done uninstall-encDATA: @$(NORMAL_UNINSTALL) @list='$(enc_DATA)'; test -n "$(encdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(encdir)'; $(am__uninstall_files_from_dir) install-glyphlistDATA: $(glyphlist_DATA) @$(NORMAL_INSTALL) @list='$(glyphlist_DATA)'; test -n "$(glyphlistdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(glyphlistdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(glyphlistdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(glyphlistdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(glyphlistdir)" || exit $$?; \ done uninstall-glyphlistDATA: @$(NORMAL_UNINSTALL) @list='$(glyphlist_DATA)'; test -n "$(glyphlistdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(glyphlistdir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build/sub \ && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile $(DATA) autoconf.h installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(encdir)" "$(DESTDIR)$(glyphlistdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-encDATA install-glyphlistDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-encDATA uninstall-glyphlistDATA .MAKE: $(am__recursive_targets) all install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-cscope clean-generic \ cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ dist-gzip dist-hook dist-lzip dist-shar dist-tarZ dist-xz \ dist-zip distcheck distclean distclean-generic distclean-hdr \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-encDATA install-exec install-exec-am \ install-glyphlistDATA install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-encDATA uninstall-glyphlistDATA .PRECIOUS: Makefile liblcdf libefont: cd $@ && $(MAKE) libefont: liblcdf cfftot1 mmafm mmpfb otfinfo otftotfm t1dotlessj t1lint t1rawafm \ t1reencode t1testpage ttftotype42: liblcdf libefont cd $@ && $(MAKE) versionize: perl -pi -e 's/^\.ds V.*/.ds V $(VERSION)/;' $(srcdir)/cfftot1/cfftot1.1 $(srcdir)/mmafm/mmafm.1 $(srcdir)/mmpfb/mmpfb.1 $(srcdir)/otfinfo/otfinfo.1 $(srcdir)/otftotfm/otftotfm.1 $(srcdir)/t1dotlessj/t1dotlessj.1 $(srcdir)/t1lint/t1lint.1 $(srcdir)/t1rawafm/t1rawafm.1 $(srcdir)/t1reencode/t1reencode.1 $(srcdir)/t1testpage/t1testpage.1 $(srcdir)/ttftotype42/ttftotype42.1 perl -pi -e 's/^(\U$(PACKAGE)\E) [\d.ab]+$$/$$1 $(VERSION)/;' $(srcdir)/README.md perl -pi -e 's/^Version: [\d.ab]+$$/Version: $(VERSION)/;' $(srcdir)/lcdf-typetools.spec dist-hook: if test -f $(srcdir)/make-glyphtounicode.pl; then (cd $(srcdir); perl make-glyphtounicode.pl) > $(distdir)/glyphtounicode.tex; elif test -f $(srcdir)/glyphtounicode.tex; then cp $(srcdir)/glyphtounicode.tex $(distdir); fi $(srcdir)/glyphtounicode.tex: $(srcdir)/glyphlist.txt $(srcdir)/texglyphlist.txt $(srcdir)/texglyphlist-g2u.txt $(srcdir)/make-glyphtounicode.pl cd $(srcdir); perl make-glyphtounicode.pl > glyphtounicode.tex .PHONY: rpm liblcdf libefont cfftot1 mmafm mmpfb otfinfo otftotfm t1dotlessj t1lint t1rawafm t1reencode t1testpage ttftotype42 # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lcdf-typetools-2.108/aclocal.m40000644000175000017500000012543413423376573013303 00000000000000# generated automatically by aclocal 1.15.1 -*- Autoconf -*- # Copyright (C) 1996-2017 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # Copyright (C) 2002-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.15.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.15.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering # Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAINTAINER_MODE([DEFAULT-MODE]) # ---------------------------------- # Control maintainer-specific portions of Makefiles. # Default is to disable them, unless 'enable' is passed literally. # For symmetry, 'disable' may be passed as well. Anyway, the user # can override the default with the --enable/--disable switch. AC_DEFUN([AM_MAINTAINER_MODE], [m4_case(m4_default([$1], [disable]), [enable], [m4_define([am_maintainer_other], [disable])], [disable], [m4_define([am_maintainer_other], [enable])], [m4_define([am_maintainer_other], [enable]) m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) dnl maintainer-mode's default is 'disable' unless 'enable' is passed AC_ARG_ENABLE([maintainer-mode], [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], am_maintainer_other[ make rules and dependencies not useful (and sometimes confusing) to the casual installer])], [USE_MAINTAINER_MODE=$enableval], [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) AC_MSG_RESULT([$USE_MAINTAINER_MODE]) AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) MAINT=$MAINTAINER_MODE_TRUE AC_SUBST([MAINT])dnl ] ) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR lcdf-typetools-2.108/mmafm/0000755000175000017500000000000013423377073012603 500000000000000lcdf-typetools-2.108/mmafm/main.cc0000644000175000017500000002703113423375327013761 00000000000000/* main.cc -- driver for mmafm program * * Copyright (c) 1997-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_CTIME # include #endif #define WEIGHT_OPT 300 #define WIDTH_OPT 301 #define OPSIZE_OPT 302 #define STYLE_OPT 303 #define N1_OPT 304 #define N2_OPT 305 #define N3_OPT 306 #define N4_OPT 307 #define VERSION_OPT 308 #define HELP_OPT 309 #define OUTPUT_OPT 310 #define PRECISION_OPT 311 #define KERN_PREC_OPT 312 const Clp_Option options[] = { { "1", '1', N1_OPT, Clp_ValDouble, 0 }, { "2", '2', N2_OPT, Clp_ValDouble, 0 }, { "3", '3', N3_OPT, Clp_ValDouble, 0 }, { "4", '4', N4_OPT, Clp_ValDouble, 0 }, { "weight", 'w', WEIGHT_OPT, Clp_ValDouble, 0 }, { "width", 'W', WIDTH_OPT, Clp_ValDouble, 0 }, { "optical-size", 'O', OPSIZE_OPT, Clp_ValDouble, 0 }, { "style", 0, STYLE_OPT, Clp_ValDouble, 0 }, { "wt", 0, WEIGHT_OPT, Clp_ValDouble, 0 }, { "wd", 0, WIDTH_OPT, Clp_ValDouble, 0 }, { "min-kern", 'k', KERN_PREC_OPT, Clp_ValDouble, 0 }, { "minimum-kern", 'k', KERN_PREC_OPT, Clp_ValDouble, 0 }, { "kern-precision", 'k', KERN_PREC_OPT, Clp_ValDouble, 0 }, { "output", 'o', OUTPUT_OPT, Clp_ValString, 0 }, { "precision", 'p', PRECISION_OPT, Clp_ValInt, 0 }, { "version", 'v', VERSION_OPT, 0, 0 }, { "help", 'h', HELP_OPT, 0, 0 }, }; using namespace Efont; static const char *program_name; static ErrorHandler *errh; static AmfmMetrics *amfm; static Vector ax_names; static Vector ax_nums; static Vector values; static void set_design(PermString a, double v) { ax_names.push_back(a); ax_nums.push_back(-1); values.push_back(v); } static void set_design(int a, double v) { ax_names.push_back(PermString()); ax_nums.push_back(a); values.push_back(v); } static void set_amfm(AmfmMetrics *a) { if (a) { if (amfm) errh->fatal("already read one AMFM file"); amfm = a; } } // apply precision static inline void pround(double &v, double multiplier, double divider) { if (KNOWN(v)) v = floor(v * multiplier + 0.5) * divider; } static void apply_precision(Metrics *m, int precision) { if (precision < 0) return; double multiplier = 1, divider = 1; for (int i = 0; i < precision; i++) multiplier *= 10, divider /= 10; for (int i = 0; i < m->nfd(); i++) pround(m->fd(i), multiplier, divider); for (int i = 0; i < m->nglyphs(); i++) { pround(m->wd(i), multiplier, divider); pround(m->lf(i), multiplier, divider); pround(m->bt(i), multiplier, divider); pround(m->rt(i), multiplier, divider); pround(m->tp(i), multiplier, divider); } for (int i = 0; i < m->nkv(); i++) pround(m->kv(i), multiplier, divider); } static void apply_kern_precision(Metrics *m, double kern_precision) { if (kern_precision <= 0) return; for (int i = 0; i < m->nkv(); i++) if (fabs(m->kv(i)) < kern_precision) m->kv(i) = 0; } static void read_file(const char *fn, MetricsFinder *finder) { Filename filename; FILE *file; if (strcmp(fn, "-") == 0) { filename = Filename(""); file = stdin; } else { filename = Filename(fn); file = filename.open_read(); } int save_errno = errno; if (!file) { // look for a font by name AmfmMetrics *new_amfm = finder->find_amfm(fn, errh); if (new_amfm) { set_amfm(new_amfm); return; } if (finder->find_metrics(fn, errh)) return; // check for instance name. don't use InstanceMetricsFinder. const char *underscore = strchr(fn, '_'); if (underscore) new_amfm = finder->find_amfm(PermString(fn, underscore - fn), errh); if (!new_amfm) errh->fatal("%s: %s", fn, strerror(save_errno)); set_amfm(new_amfm); int i = 0; while (underscore[0] == '_' && underscore[1]) { double x = strtod(underscore + 1, const_cast(&underscore)); set_design(i, x); i++; } return; } Slurper slurper(filename, file); bool is_afm = false; if (file != stdin) { char *first_line = slurper.peek_line(); if (first_line) is_afm = strncmp(first_line, "StartFontMetrics", 16) == 0; } if (is_afm) { Metrics *afm = AfmReader::read(slurper, errh); if (afm) finder->record(afm); } else set_amfm(AmfmReader::read(slurper, finder, errh)); } static void usage_error(const char *error_message, ...) { va_list val; va_start(val, error_message); if (!error_message) errh->message("Usage: %s [OPTION | FONT]...", program_name); else errh->xmessage(ErrorHandler::e_error, error_message, val); errh->message("Type %s --help for more information.", program_name); exit(1); } static void usage() { FileErrorHandler uerrh(stdout); uerrh.message("\ % creates an AFM font metrics file for a multiple master font by\n\ interpolating at a point you specify and writes it to the standard output.\n\ \n\ Usage: %s [OPTION | FONT]...\n\ \n\ Each FONT is either an AFM or AMFM file name, or the font name of a multiple\n\ master font. In the second case, mmafm will find the actual AMFM file using\n\ the PSRESOURCEPATH environment variable.\n\ \n\ General options:\n\ -o, --output=FILE Write output to FILE.\n\ -h, --help Print this message and exit.\n\ -v, --version Print version number and warranty and exit.\n\ \n\ Interpolation settings:\n\ -w, --weight=N Set weight to N.\n\ -W, --width=N Set width to N.\n\ -O, --optical-size=N Set optical size to N.\n\ --style=N Set style axis to N.\n\ --1=N, --2=N, --3=N, --4=N Set first (second, third, fourth) axis to N.\n\ -p, --precision=N Allow N digits of fraction (default 3).\n\ -k, --min-kern=N Remove kerns smaller than N (default 2).\n\ \n\ Report bugs to .\n", program_name); } int main(int argc, char *argv[]) { MetricsFinder *finder = new CacheMetricsFinder; PsresDatabase *psres = new PsresDatabase; psres->add_psres_path(getenv("PSRESOURCEPATH"), 0, false); PsresMetricsFinder *psres_finder = new PsresMetricsFinder(psres); finder->add_finder(psres_finder); Clp_Parser *clp = Clp_NewParser(argc, (const char * const *)argv, sizeof(options) / sizeof(options[0]), options); program_name = Clp_ProgramName(clp); errh = ErrorHandler::static_initialize(new FileErrorHandler(stderr, String(program_name) + ": ")); FILE *output_file = 0; int precision = 3; double kern_precision = 2.0; while (1) { int opt = Clp_Next(clp); switch (opt) { case WEIGHT_OPT: set_design("Weight", clp->val.d); break; case WIDTH_OPT: set_design("Width", clp->val.d); break; case OPSIZE_OPT: set_design("OpticalSize", clp->val.d); break; case STYLE_OPT: set_design("Style", clp->val.d); break; case N1_OPT: case N2_OPT: case N3_OPT: case N4_OPT: set_design(opt - N1_OPT, clp->val.d); break; case PRECISION_OPT: precision = clp->val.i; break; case KERN_PREC_OPT: kern_precision = clp->val.d; break; case OUTPUT_OPT: if (output_file) errh->fatal("output file already specified"); if (strcmp(clp->vstr, "-") == 0) output_file = stdout; else { output_file = fopen(clp->vstr, "wb"); if (!output_file) errh->fatal("%s: %s", clp->vstr, strerror(errno)); } break; case HELP_OPT: usage(); exit(0); break; case VERSION_OPT: printf("mmafm (LCDF typetools) %s\n", VERSION); printf("Copyright (C) 1997-2019 Eddie Kohler\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); exit(0); break; case Clp_NotOption: read_file(clp->vstr, finder); break; case Clp_Done: goto done; case Clp_BadOption: usage_error(0); break; } } done: if (!amfm) usage_error("missing font argument"); MultipleMasterSpace *mmspace = amfm->mmspace(); #if MMAFM_RUN_MMPFB if (!mmspace->check_intermediate()) { char *buf = new char[amfm->font_name().length() + 30]; sprintf(buf, "mmpfb -q --amcp-info '%s'", amfm->font_name().c_str()); FILE *f = popen(buf, "r"); if (f) { Filename fake(""); Slurper slurpy(fake, f); AmfmReader::add_amcp_file(slurpy, amfm, errh); pclose(f); } delete[] buf; } #endif Vector design = mmspace->default_design_vector(); for (int i = 0; i < values.size(); i++) if (ax_names[i]) mmspace->set_design(design, ax_names[i], values[i], errh); else mmspace->set_design(design, ax_nums[i], values[i], errh); Vector weight; if (!mmspace->design_to_weight(design, weight, errh)) { if (!mmspace->check_intermediate()) { errh->message("(I can%,t interpolate font programs with intermediate masters on my own."); #if MMAFM_RUN_MMPFB errh->message("I tried to run %, but it didn't work.", amfm->font_name().c_str()); errh->message("Maybe your PSRESOURCEPATH environment variable is not set?"); #endif errh->fatal("See the manual page for more information.)"); } else errh->fatal("can%,t create weight vector"); } // Need to check for case when all design coordinates are unspecified. The // AMFM file contains a default WeightVector, but often NOT a default // DesignVector; we don't want to generate a file with a FontName like // `MyriadMM_-9.79797979e97_-9.79797979e97_' because the DesignVector // components are unknown. if (!KNOWN(design[0])) errh->fatal("must specify %s%,s %s coordinate", amfm->font_name().c_str(), mmspace->axis_type(0).c_str()); Metrics *m = amfm->interpolate(design, weight, errh); if (m) { // Add a comment identifying this as interpolated by mmafm if (MetricsXt *xt = m->find_xt("AFM")) { AfmMetricsXt *afm_xt = (AfmMetricsXt *)xt; #if HAVE_CTIME time_t cur_time = time(0); char *time_str = ctime(&cur_time); int time_len = strlen(time_str) - 1; char *buf = new char[strlen(VERSION) + time_len + 100]; sprintf(buf, "Interpolated by mmafm-%s on %.*s.", VERSION, time_len, time_str); #else char *buf = new char[strlen(VERSION) + 100]; sprintf(buf, "Interpolated by mmafm-%s.", VERSION); #endif afm_xt->opening_comments.push_back(buf); afm_xt->opening_comments.push_back("Mmafm is free software. See ."); delete[] buf; } // round numbers if necessary if (precision >= 0) apply_precision(m, precision); if (kern_precision > 0) apply_kern_precision(m, kern_precision); // write the output file if (!output_file) output_file = stdout; AfmWriter::write(m, output_file); return 0; } else return 1; } lcdf-typetools-2.108/mmafm/Makefile.in0000644000175000017500000005072513423376574014606 00000000000000# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : bin_PROGRAMS = mmafm$(EXEEXT) subdir = mmafm ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/lcdf-typetools.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/autoconf.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" PROGRAMS = $(bin_PROGRAMS) am_mmafm_OBJECTS = main.$(OBJEXT) mmafm_OBJECTS = $(am_mmafm_OBJECTS) mmafm_DEPENDENCIES = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(mmafm_SOURCES) DIST_SOURCES = $(mmafm_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KPATHSEA_DEPEND = @KPATHSEA_DEPEND@ KPATHSEA_INCLUDES = @KPATHSEA_INCLUDES@ KPATHSEA_LIBS = @KPATHSEA_LIBS@ KPATHSEA_RULE = @KPATHSEA_RULE@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SELECTED_SUBDIRS = @SELECTED_SUBDIRS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TEMPLATE_OBJS = @TEMPLATE_OBJS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ encdir = @encdir@ exec_prefix = @exec_prefix@ glyphlistdir = @glyphlistdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign man_MANS = mmafm.1 mmafm_SOURCES = main.cc mmafm_LDADD = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_CPPFLAGS = -I$(srcdir)/../include CLEANFILES = @TEMPLATE_OBJS@ EXTRA_DIST = mmafm.1 all: all-am .SUFFIXES: .SUFFIXES: .cc .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign mmafm/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign mmafm/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) mmafm$(EXEEXT): $(mmafm_OBJECTS) $(mmafm_DEPENDENCIES) $(EXTRA_mmafm_DEPENDENCIES) @rm -f mmafm$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(mmafm_OBJECTS) $(mmafm_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-man uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-binPROGRAMS install-data install-data-am \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-man1 install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-binPROGRAMS uninstall-man uninstall-man1 .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lcdf-typetools-2.108/mmafm/Makefile.am0000664000175000017500000000045312732752520014557 00000000000000## Process this file with automake to produce Makefile.in AUTOMAKE_OPTIONS = foreign bin_PROGRAMS = mmafm man_MANS = mmafm.1 mmafm_SOURCES = main.cc mmafm_LDADD = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_CPPFLAGS = -I$(srcdir)/../include CLEANFILES = @TEMPLATE_OBJS@ EXTRA_DIST = mmafm.1 lcdf-typetools-2.108/mmafm/mmafm.10000644000175000017500000001062513423376706013710 00000000000000.\" -*-nroff-*- .ds V 2.108 .de M .BR "\\$1" "(\\$2)\\$3" .. .ds E " \-\- .if t .ds E \(em .de Op .BR "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" .. .de Oy .BI "\\$1\fR=" "\\$2\fR, " "\\$3\& " "\\$4" "\\$5" "\\$6" .. .de Ol .BI "\\$1\fR=" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" .. .de Sp .if n .sp .if t .sp 0.4 .. .de Es .Sp .RS 5 .nf .. .de Ee .fi .RE .PP .. .TH MMAFM 1 "LCDF Typetools" "Version \*V" .SH NAME mmafm \- creates AFM font metrics for multiple master fonts ' .SH SYNOPSIS .B mmafm \%[OPTIONS...] .I font ' .SH DESCRIPTION .B Mmafm creates AFM font metrics for PostScript multiple master fonts by interpolation. You pass it an AMFM file (multiple master font metrics) and options specifying the design point you want, and it writes the resulting AFM file to the standard output. .PP Each .I font argument is either the filename of an AFM or AMFM font metrics file, or a PostScript font name. If you give a font name, .B mmafm will look up the actual font metrics file using the PSRESOURCEPATH environment variable. This colon-separated path is searched for `PSres.upr' files, an Adobe method for indexing PostScript resources. .PP You can also give the name of a multiple master font instance, like `MinionMM_367_400_12_'. .B Mmafm will parse the font name and create that instance for you. `PSres.upr' files must be set up for this to work. .PP Any multiple master font should be distributed with a single AMFM file and several AFM files (one for each master). For Myriad, for example, the AMFM file is MyriadMM.amfm and the AFM files are MyriadMM-LightCn.afm, MyriadMM-LightSemiEx.afm, MyriadMM-BlackCn.afm, and MyriadMM-BlackSemiEx.afm. .B Mmafm needs to find all these files to function. For fonts in the Adobe type library, you can download the necessary files from ; look for the mm-metrics package. .PP You must always supply the AMFM file (or its font name) on the command line, but .B mmafm will look for any required AFM files you don't supply yourself. It tries the PSRESOURCEPATH environment variable, and also looks for files named `\fIFontName\fR.afm' or `\fIFontName\fR.AFM' in the directory that contained the AMFM file. (The Myriad filenames given above fit this pattern.) .PP .B Mmafm supports fonts with intermediate masters, like Adobe Jenson and Kepler. If your PSRESOURCEPATH environment variable is set up, it will handle these fonts automatically. Otherwise, you must first run .RB ` "mmpfb \-\-amcp\-info" ' on the font outline files to create auxiliary AMCP files for these fonts. Each AMCP file should be in the same directory as its corresponding AMFM file and should have the same root filename, but with a `.amcp' extension instead of `.amfm'. See .M mmpfb 1 for more information. ' ' .SH EXAMPLE ' .nf % mmafm \-\-weight=400 \-\-width=600 MyriadMM.amfm > MyriadMM_400_600_.afm .fi ' .SH OPTIONS Long options may be abbreviated to their unique prefixes. ' .TP 5 .Oy \-\-output file \-o file Send output to .I file instead of standard output. ' .TP .Oy \-\-weight N \-w N Set the weight axis to .IR N . ' .TP .Oy \-\-width N \-W N Set the width axis to .IR N . ' .TP .Oy \-\-optical\-size N \-O N Set the optical size axis to .IR N . ' .TP .Ol \-\-style N Set the style axis to .IR N . .TP \fB\-\-1\fR=\fIN\fR (\fB\-\-2\fR=\fIN\fR, \fB\-\-3\fR=\fIN\fR, \fB\-\-4\fR=\fIN\fR) Set the first (second, third, fourth) axis to .IR N . ' .TP .Oy \-\-precision N \-p N Round output numbers so they have at most .I N digits after the decimal point. Smaller numbers are less precise; `\fB\-p \fR0' rounds all numbers to integers. The default precision is 3. ' .TP .Oy \-\-min\-kern N \-k N Only output kerning pairs whose absolute value is .IR N or larger. Smaller minimum kerns make kerning more precise and the output AFM file bigger. The default minimum kern is 2.0. ' .SH TROUBLESHOOTING .PP Some programs, such as TeX's .BR fontinst , can choke on AFM files that include fractional numbers. Therefore, if you have trouble with an AFM file, try rerunning .B mmafm with the .Op \-\-precision=0 option. ' .SH SEE ALSO .M mmpfb 1 ' .SH DIAGNOSTICS .TP 5 \fIFont\fR requires intermediate master conversion programs You haven't yet created an AMCP file for \fIFont\fR. ' .SH AUTHOR .na Eddie Kohler, ekohler@gmail.com .PP The latest version is available from: .br http://www.lcdf.org/type/ .br AMFM and AFM files for Adobe Type Library fonts are also available at that URL. .PP Thanks to Melissa O'Neill for suggestions and patient debugging. lcdf-typetools-2.108/depcomp0000755000175000017500000005601612732752554013016 00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2013-05-30.07; # UTC # Copyright (C) 1999-2014 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac # Get the directory component of the given path, and save it in the # global variables '$dir'. Note that this directory component will # be either empty or ending with a '/' character. This is deliberate. set_dir_from () { case $1 in */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; *) dir=;; esac } # Get the suffix-stripped basename of the given path, and save it the # global variable '$base'. set_base_from () { base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` } # If no dependency file was actually created by the compiler invocation, # we still have to create a dummy depfile, to avoid errors with the # Makefile "include basename.Plo" scheme. make_dummy_depfile () { echo "#dummy" > "$depfile" } # Factor out some common post-processing of the generated depfile. # Requires the auxiliary global variable '$tmpdepfile' to be set. aix_post_process_depfile () { # If the compiler actually managed to produce a dependency file, # post-process it. if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependency.h'. # Do two passes, one to just change these to # $object: dependency.h # and one to simply output # dependency.h: # which is needed to avoid the deleted-header problem. { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" } > "$depfile" rm -f "$tmpdepfile" else make_dummy_depfile fi } # A tabulation character. tab=' ' # A newline character. nl=' ' # Character ranges might be problematic outside the C locale. # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz digits=0123456789 alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Avoid interferences from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. ## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). Also, it might not be ## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The second -e expression handles DOS-style file names with drive # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done aix_post_process_depfile ;; tcc) # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 # FIXME: That version still under development at the moment of writing. # Make that this statement remains true also for stable, released # versions. # It will wrap lines (doesn't matter whether long or short) with a # trailing '\', as in: # # foo.o : \ # foo.c \ # foo.h \ # # It will put a trailing '\' even on the last line, and will use leading # spaces rather than leading tabs (at least since its commit 0394caf7 # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. # We have to change lines of the first kind to '$object: \'. sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" # And for each line of the second kind, we have to emit a 'dep.h:' # dummy dependency, to avoid the deleted-header problem. sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; ## The order of this option in the case statement is important, since the ## shell code in configure will try each of these formats in the order ## listed in this file. A plain '-MD' option would be understood by many ## compilers, so we must ensure this comes after the gcc and icc options. pgcc) # Portland's C compiler understands '-MD'. # Will always output deps to 'file.d' where file is the root name of the # source file under compilation, even if file resides in a subdirectory. # The object file name does not affect the name of the '.d' file. # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... set_dir_from "$object" # Use the source, not the object, to determine the base name, since # that's sadly what pgcc will do too. set_base_from "$source" tmpdepfile=$base.d # For projects that build the same source file twice into different object # files, the pgcc approach of using the *source* file root name can cause # problems in parallel builds. Use a locking strategy to avoid stomping on # the same $tmpdepfile. lockdir=$base.d-lock trap " echo '$0: caught signal, cleaning up...' >&2 rmdir '$lockdir' exit 1 " 1 2 13 15 numtries=100 i=$numtries while test $i -gt 0; do # mkdir is a portable test-and-set. if mkdir "$lockdir" 2>/dev/null; then # This process acquired the lock. "$@" -MD stat=$? # Release the lock. rmdir "$lockdir" break else # If the lock is being held by a different process, wait # until the winning process is done or we timeout. while test -d "$lockdir" && test $i -gt 0; do sleep 1 i=`expr $i - 1` done fi i=`expr $i - 1` done trap - 1 2 13 15 if test $i -le 0; then echo "$0: failed to acquire lock after $numtries attempts" >&2 echo "$0: check lockdir '$lockdir'" >&2 exit 1 fi if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then # Libtool generates 2 separate objects for the 2 libraries. These # two compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir$base.o.d # libtool 1.5 tmpdepfile2=$dir.libs/$base.o.d # Likewise. tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d "$@" -MD fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done # Same post-processing that is required for AIX mode. aix_post_process_depfile ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this sed invocation # correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process the last invocation # correctly. Breaking it into two sed invocations is a workaround. sed '1,2d' "$tmpdepfile" \ | tr ' ' "$nl" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E \ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: lcdf-typetools-2.108/otftotfm/0000755000175000017500000000000013423377073013350 500000000000000lcdf-typetools-2.108/otftotfm/dvipsencoding.hh0000644000175000017500000001036113423375330016440 00000000000000#ifndef OTFTOTFM_DVIPSENCODING_HH #define OTFTOTFM_DVIPSENCODING_HH #include #include #include class Metrics; class Secondary; class FontInfo; class DvipsEncoding { public: DvipsEncoding(); static void add_glyphlist(String); operator bool() const { return _e.size() > 0; } const String &name() const { return _name; } const String &filename() const { return _filename; } int boundary_char() const { return _boundary_char; } const String &coding_scheme() const { return _coding_scheme; } void set_coding_scheme(const String &s) { _coding_scheme = s; } void set_warn_missing(bool wm) { _warn_missing = wm; } void encode(int, PermString); inline int encoding_of(PermString) const; int encoding_of(PermString, bool encode); inline bool encoded(int e) const; inline PermString encoding(int e) const; int encoding_size() const { return _e.size(); } int parse(String filename, bool ignore_ligkern, bool ignore_other, ErrorHandler *); int parse_ligkern(const String &ligkern_text, int override, ErrorHandler *); int parse_position(const String &ligkern_text, int override, ErrorHandler *); int parse_unicoding(const String &unicoding_text, int override, ErrorHandler *); bool file_had_ligkern() const { return _file_had_ligkern; } // also modifies 'this': void make_metrics(Metrics &, const FontInfo &, Secondary *, bool literal, ErrorHandler *); void make_base_mappings(Vector &mappings, const FontInfo &); void apply_ligkern_lig(Metrics &, ErrorHandler *) const; void apply_ligkern_kern(Metrics &, ErrorHandler *) const; void apply_position(Metrics &, ErrorHandler *) const; enum { JT_KERN = 32, JT_LIG = 64, JT_ADDLIG = 128, JT_LIGALL = 199, JL_LIG = JT_LIG | JT_ADDLIG, JL_CLIG = JL_LIG | 1, JL_CLIG_S = JL_LIG | 2, JL_LIGC = JL_LIG | 3, JL_LIGC_S = JL_LIG | 4, JL_CLIGC = JL_LIG | 5, JL_CLIGC_S = JL_LIG | 6, JL_CLIGC_SS = JL_LIG | 7, JT_NOLIGKERN = JT_KERN | JT_LIG, J_ALL = 0x7FFFFFFF }; // also see nokern_names in dvipsencoding.cc private: struct Ligature { int c1, c2, join, k, d; }; Vector _e; Vector _encoding_required; int _boundary_char; int _altselector_char; Vector _lig; Vector _pos; HashMap _unicoding_map; Vector _unicoding; mutable Vector _unicodes; String _name; String _filename; String _printable_filename; String _coding_scheme; String _initial_comment; String _final_text; bool _file_had_ligkern; bool _warn_missing; struct WordType { const char *name; int (DvipsEncoding::*parsefunc)(Vector&, int, ErrorHandler*); }; static const WordType word_types[]; enum { WT_LIGKERN = 0, WT_POSITION, WT_UNICODING }; void add_ligkern(const Ligature &, int override); enum { EPARSE = 90000 }; int parse_ligkern_words(Vector &, int override, ErrorHandler *); int parse_position_words(Vector &, int override, ErrorHandler *); int parse_unicoding_words(Vector &, int override, ErrorHandler *); void parse_word_group(Vector &, int override, int wt, ErrorHandler *); int parse_words(const String &, int override, int wt, ErrorHandler *); void bad_codepoint(int, Metrics &, HashMap &bad_unicodes); bool x_unicodes(PermString chname, Vector &unicodes) const; String landmark(int line) const; static PermString dot_notdef; static bool glyphname_unicode(String, Vector &); friend inline bool operator==(const Ligature&, const Ligature&); }; inline bool DvipsEncoding::encoded(int e) const { return e >= 0 && e < _e.size() && _e[e] != dot_notdef; } inline PermString DvipsEncoding::encoding(int e) const { if (encoded(e)) return _e[e]; else return PermString(); } inline int DvipsEncoding::encoding_of(PermString what) const { return const_cast(this)->encoding_of(what, false); } #endif lcdf-typetools-2.108/otftotfm/automatic.hh0000644000175000017500000000224413423375330015573 00000000000000#ifndef OTFTOTFM_AUTOMATIC_HH #define OTFTOTFM_AUTOMATIC_HH #include class ErrorHandler; enum { O_ENCODING = 0, O_TFM, O_PL, O_VF, O_VPL, O_TYPE1, O_MAP, O_MAP_PARENT, O_TRUETYPE, O_OPENTYPE, O_TYPE42, NUMODIR }; extern bool automatic; extern bool no_create; String getodir(int o, ErrorHandler *); void setodir(int o, const String &); bool set_vendor(const String &); bool set_typeface(const String &, bool override); bool set_map_file(const String &); const char *odirname(int o); void update_odir(int o, String file, ErrorHandler *); String installed_type1(const String &otf_filename, const String &ps_fontname, bool allow_generate, ErrorHandler *); String installed_type1_dotlessj(const String &otf_filename, const String &ps_fontname, bool allow_generate, ErrorHandler *); String installed_truetype(const String &ttf_filename, bool allow_generate, ErrorHandler *errh); String installed_type42(const String &ttf_filename, const String &ps_fontname, bool allow_generate, ErrorHandler *errh); int update_autofont_map(const String &fontname, String mapline, ErrorHandler *); String locate_encoding(String encfile, ErrorHandler *, bool literal = false); #endif lcdf-typetools-2.108/otftotfm/kpseinterface.c0000644000175000017500000000463513423375330016261 00000000000000/* kpseinterface.{c,h} -- interface with the kpathsea library * * Copyright (c) 2003-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #include #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include "kpseinterface.h" int kpsei_env_sep_char = ENV_SEP; void kpsei_init(const char* argv0, const char* progname) { kpse_set_program_name(argv0, progname); #ifdef SELFAUTODIR putenv("SELFAUTODIR=" SELFAUTODIR); #endif #ifdef SELFAUTOLOC putenv("SELFAUTOLOC=" SELFAUTOLOC); #endif #ifdef SELFAUTOPARENT putenv("SELFAUTOPARENT=" SELFAUTOPARENT); #endif #ifdef SELFAUTOGRANDPARENT putenv("SELFAUTOGRANDPARENT=" SELFAUTOGRANDPARENT); #endif } char* kpsei_path_expand(const char* path) { return kpse_path_expand(path); } char* kpsei_find_file(const char* name, int format) { char *result; switch (format) { case KPSEI_FMT_WEB2C: return kpse_find_file(name, kpse_web2c_format, true); case KPSEI_FMT_ENCODING: #if HAVE_DECL_KPSE_ENC_FORMAT if ((result = kpse_find_file(name, kpse_enc_format, true))) return result; #endif return kpse_find_file(name, kpse_tex_ps_header_format, true); case KPSEI_FMT_TYPE1: return kpse_find_file(name, kpse_type1_format, false); case KPSEI_FMT_TYPE42: return kpse_find_file(name, kpse_type42_format, false); case KPSEI_FMT_TRUETYPE: return kpse_find_file(name, kpse_truetype_format, false); #if HAVE_DECL_KPSE_OPENTYPE_FORMAT case KPSEI_FMT_OPENTYPE: return kpse_find_file(name, kpse_opentype_format, false); #endif case KPSEI_FMT_OTHER_TEXT: return kpse_find_file(name, kpse_program_text_format, true); case KPSEI_FMT_MAP: return kpse_find_file(name, kpse_fontmap_format, true); default: return 0; } } void kpsei_set_debug_flags(unsigned flags) { kpathsea_debug = flags; } lcdf-typetools-2.108/otftotfm/util.cc0000644000175000017500000001761513423375330014560 00000000000000/* util.{cc,hh} -- various bits * * Copyright (c) 2003-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include "util.hh" #include #include #include #include #include #include #include #ifdef HAVE_FCNTL_H # include #endif #if defined(_MSDOS) || defined(_WIN32) # include #endif #ifdef HAVE_UNISTD_H # include #endif String read_file(String filename, ErrorHandler *errh, bool warning) { FILE *f; if (!filename || filename == "-") { filename = ""; f = stdin; #if defined(_MSDOS) || defined(_WIN32) // Set the file mode to binary _setmode(_fileno(f), _O_BINARY); #endif } else if (!(f = fopen(filename.c_str(), "rb"))) { errh->xmessage((warning ? errh->e_warning : errh->e_error) + ErrorHandler::make_landmark_anno(filename), strerror(errno)); return String(); } StringAccum sa; int amt; do { if (char *x = sa.reserve(8192)) { amt = fread(x, 1, 8192, f); sa.adjust_length(amt); } else amt = 0; } while (amt != 0); if (!feof(f) || ferror(f)) errh->xmessage((warning ? errh->e_warning : errh->e_error) + ErrorHandler::make_landmark_anno(filename), strerror(errno)); if (f != stdin) fclose(f); return sa.take_string(); } String printable_filename(const String &s) { if (!s || s == "-") return String::make_stable(""); else return s; } String pathname_filename(const String &path) { int slash = path.find_right('/'); if (slash >= 0 && slash != path.length() - 1) return path.substring(slash + 1); else return path; } static String simplify_filename(String x) { while (x.substring(0, 2) == "./") x = x.substring(2); int pos; while ((pos = x.find_left("/./")) >= 0) x = x.substring(0, pos) + x.substring(pos + 2); return x; } bool same_filename(const String &a, const String &b) { return simplify_filename(a) == simplify_filename(b); } String shell_quote(const String &str) { if (!str) return String::make_stable("\"\""); const char *begin = str.begin(); const char *end = str.end(); StringAccum sa; #if defined(_MSDOS) || defined(_WIN32) sa.append('\"'); for (const char *s = begin; s < end; ++s) if (isalnum((unsigned char) *s) || *s == '_' || *s == '-' || *s == '+' || *s == '\\' || *s == ':' || *s == '.') /* do nothing */; else if (*s == '\"') { sa.append(begin, s); sa.append("\"\"\"", 3); begin = s + 1; } else { sa.append(begin, s + 1); begin = s + 1; } if (sa.length() > 1) { sa.append(begin, end); sa.append('\"'); return sa.take_string(); } #else for (const char *s = begin; s < end; s++) if (isalnum((unsigned char) *s) || *s == '_' || *s == '-' || *s == '+' || *s == '/' || *s == ':' || *s == '.') /* do nothing */; else { sa.append(begin, s); sa.append('\\'); begin = s; } if (sa.length()) { sa.append(begin, end); return sa.take_string(); } #endif return str; } int mysystem(const char *command, ErrorHandler *errh) { if (no_create) { errh->message("would run %s", command); return 0; } else { if (verbose) errh->message("running %s", command); return system(command); } } FILE* mypopen(const char* command, const char* type, ErrorHandler* errh) { if (no_create) { errh->message("would run %s", command); return popen("true", type); } else { if (verbose) errh->message("running %s", command); return popen(command, type); } } #if !HAVE_MKSTEMP static const char * my_tmpnam() { # ifndef WIN32 return tmpnam(0); # else const char *dir = getenv("TEMP"); return _tempnam(dir ? dir : ".", "otftmp."); # endif } #endif int temporary_file(String &filename, ErrorHandler *errh) { if (no_create) return 0; // random number suffices #if HAVE_MKSTEMP const char *tmpdir = getenv("TMPDIR"); if (tmpdir) filename = String(tmpdir) + "/otftotfm.XXXXXX"; else { # ifdef P_tmpdir filename = P_tmpdir "/otftotfm.XXXXXX"; # else filename = "/tmp/otftotfm.XXXXXX"; # endif } int fd = mkstemp(filename.mutable_c_str()); if (fd < 0) errh->error("temporary file %<%s%>: %s", filename.c_str(), strerror(errno)); return fd; #else // !HAVE_MKSTEMP for (int tries = 0; tries < 5; tries++) { if (!(filename = my_tmpnam())) return errh->error("cannot create temporary file"); # ifdef O_EXCL int fd = ::open(filename.c_str(), O_RDWR | O_CREAT | O_EXCL | O_TRUNC, 0600); # else int fd = ::open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC, 0600); # endif if (fd >= 0) return fd; } return errh->error("temporary file %<%s%>: %s", filename.c_str(), strerror(errno)); #endif } bool parse_unicode_number(const char* begin, const char* end, int require_prefix, uint32_t& result) { bool allow_lower = (require_prefix == 1); if (require_prefix < 0) /* do not look for prefix */; else if (begin + 7 == end && begin[0] == 'u' && begin[1] == 'n' && begin[2] == 'i') begin += 3; else if (begin + 5 <= end && begin + 7 >= end && begin[0] == 'u') begin++; else if (begin + 3 <= end && begin + 8 >= end && begin[0] == 'U' && begin[1] == '+') begin += 2, allow_lower = true; else if (require_prefix > 1) /* some prefix was required */ return false; uint32_t value; for (value = 0; begin < end; begin++) if (*begin >= '0' && *begin <= '9') value = (value << 4) | (*begin - '0'); else if (*begin >= 'A' && *begin <= 'F') value = (value << 4) | (*begin - 'A' + 10); else if (allow_lower && *begin >= 'a' && *begin <= 'f') value = (value << 4) | (*begin - 'a' + 10); else return false; if (value > 0 && (value <= 0xD7FF || (value >= 0xE000 && value <= 0x10FFFF))) { result = value; return true; } else return false; } #if 0 String shell_command_output(String cmdline, const String &input, ErrorHandler *errh, bool strip_newlines) { FILE *f = tmpfile(); if (!f) errh->fatal("cannot create temporary file: %s", strerror(errno)); ignore_result(fwrite(input.data(), 1, input.length(), f)); fflush(f); rewind(f); String new_cmdline = cmdline + " 0<&" + String(fileno(f)); FILE *p = popen(new_cmdline.c_str(), "r"); if (!p) errh->fatal("%<%s%>: %s", cmdline.c_str(), strerror(errno)); StringAccum sa; int amt; do { if (char *x = sa.reserve(2048)) { amt = fread(x, 1, 2048, p); sa.adjust_length(amt); } else amt = 0; } while (amt != 0 && sa.length() < 200000); if (amt != 0) errh->warning("%<%s%> output too long, truncated", cmdline.c_str()); else if (!feof(p) || ferror(p)) errh->error("%<%s%>: %s", cmdline.c_str(), strerror(errno)); fclose(f); pclose(p); while (strip_newlines && sa && (sa.back() == '\n' || sa.back() == '\r')) sa.pop_back(); return sa.take_string(); } #endif lcdf-typetools-2.108/otftotfm/secondary.cc0000644000175000017500000005350613423375330015571 00000000000000/* secondary.{cc,hh} -- code for generating fake glyphs * * Copyright (c) 2003-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #include #include "secondary.hh" #include "metrics.hh" #include "automatic.hh" #include "otftotfm.hh" #include "util.hh" #include #include #include #include #include #include #include #include #include #include #include #include #include #include enum { U_EXCLAMDOWN = 0x00A1, // U+00A1 INVERTED EXCLAMATION MARK U_DEGREE = 0x00B0, // U+00B0 DEGREE SIGN U_QUESTIONDOWN = 0x00BF, // U+00BF INVERTED QUESTION MARK U_IJ = 0x0132, // U+0132 LATIN CAPITAL LIGATURE IJ U_ij = 0x0133, // U+0133 LATIN SMALL LIGATURE IJ U_DOTLESSJ = 0x0237, // U+0237 LATIN SMALL LETTER DOTLESS J U_RINGABOVE = 0x02DA, // U+02DA RING ABOVE U_COMBININGRINGABOVE = 0x030A, // U+030A COMBINING RING ABOVE U_CWM = 0x200C, // U+200C ZERO WIDTH NON-JOINER U_ENDASH = 0x2013, // U+2013 EN DASH U_PERTENTHOUSAND = 0x2031, // U+2031 PER TEN THOUSAND SIGN U_INTERROBANG = 0x203D, // U+203D INTERROBANG U_FRACTION = 0x2044, // U+2044 FRACTION SLASH U_CENTIGRADE = 0x2103, // U+2103 DEGREE CELSIUS U_ASTERISKMATH = 0x2217, // U+2217 ASTERISK OPERATOR U_BARDBL = 0x2225, // U+2225 PARALLEL TO U_VISIBLESPACE = 0x2423, // U+2423 OPEN BOX U_DBLBRACKETLEFT = 0x27E6, // U+27E6 MATHEMATICAL LEFT WHITE SQUARE BRACKET U_DBLBRACKETRIGHT = 0x27E7, // U+27E7 MATHEMATICAL RIGHT WHITE SQUARE BRACKET U_INTERROBANGDOWN = 0x2E18, // U+2E18 INVERTED INTERROBANG U_ALTSELECTOR = 0xD802, // invalid Unicode U_CAPITALCWM = 0xD809, // invalid Unicode U_ASCENDERCWM = 0xD80A, // invalid Unicode U_TWELVEUDASH = 0xD80C, // invalid Unicode U_RINGFITTED = 0xD80D, // invalid Unicode // BEGIN BACKWARDS COMPATIBILITY -- newer texglyphlist.txt does not include // these code points U_SS = 0xD800, // invalid Unicode U_SSSMALL = 0xD803, // invalid Unicode U_FFSMALL = 0xD804, // invalid Unicode U_FISMALL = 0xD805, // invalid Unicode U_FLSMALL = 0xD806, // invalid Unicode U_FFISMALL = 0xD807, // invalid Unicode U_FFLSMALL = 0xD808, // invalid Unicode // END BACKWARDS COMPATIBILITY U_VS1 = 0xFE00, U_VS16 = 0xFE0F, U_VS17 = 0xE0100, U_VS256 = 0xE01FF, U_DOTLESSJ_2 = 0xF6BE, U_THREEQUARTERSEMDASH = 0xF6DE, U_FSMALL = 0xF766, U_ISMALL = 0xF769, U_LSMALL = 0xF76C, U_SSMALL = 0xF773, U_MATHDOTLESSJ = 0x1D6A5 // U+1D6A5 MATHEMATICAL ITALIC SMALL DOTLESS J }; FontInfo::FontInfo(const Efont::OpenType::Font *otf_, ErrorHandler *errh) : otf(otf_), cmap(0), cff_file(0), cff(0), post(0), name(0), _nglyphs(-1), _got_glyph_names(false), _ttb_program(0), _override_is_fixed_pitch(false), _override_italic_angle(false), _override_x_height(x_height_auto) { cmap = new Efont::OpenType::Cmap(otf->table("cmap"), errh); assert(cmap->ok()); if (String cff_string = otf->table("CFF")) { cff_file = new Efont::Cff(cff_string, otf->units_per_em(), errh); if (!cff_file->ok()) return; Efont::Cff::FontParent *fp = cff_file->font(PermString(), errh); if (!fp || !fp->ok()) return; if (!(cff = dynamic_cast(fp))) { errh->error("CID-keyed fonts not supported"); return; } _nglyphs = cff->nglyphs(); } if (!cff) { post = new Efont::OpenType::Post(otf->table("post"), errh); // read number of glyphs from 'maxp' -- should probably be elsewhere if (Efont::OpenType::Data maxp = otf->table("maxp")) if (maxp.length() >= 6) _nglyphs = maxp.u16(4); if (_nglyphs < 0 && post->ok()) _nglyphs = post->nglyphs(); } name = new Efont::OpenType::Name(otf->table("name"), errh); } FontInfo::~FontInfo() { delete cmap; delete cff_file; delete post; delete name; delete _ttb_program; } bool FontInfo::ok() const { if (cff) return cmap->ok() && cff->ok(); else return post && post->ok() && name && name->ok(); } bool FontInfo::glyph_names(Vector &glyph_names) const { program()->glyph_names(glyph_names); return true; } int FontInfo::glyphid(PermString name) const { if (cff) return cff->glyphid(name); else { if (!_got_glyph_names) { glyph_names(_glyph_names); _got_glyph_names = true; } PermString *found = std::find(_glyph_names.begin(), _glyph_names.end(), name); if (found == _glyph_names.end()) return 0; return found - _glyph_names.begin(); } } String FontInfo::family_name() const { if (cff) return cff->dict_string(Efont::Cff::oFamilyName); else return name->english_name(Efont::OpenType::Name::N_FAMILY); } String FontInfo::postscript_name() const { if (cff) return cff->font_name(); else return name->english_name(Efont::OpenType::Name::N_POSTSCRIPT); } const Efont::CharstringProgram * FontInfo::program() const { if (cff) return cff; else { if (!_ttb_program) _ttb_program = new Efont::TrueTypeBoundsCharstringProgram(otf); return _ttb_program; } } bool FontInfo::is_fixed_pitch() const { if (_override_is_fixed_pitch) return _is_fixed_pitch; else if (cff) { double d; return (cff->dict_value(Efont::Cff::oIsFixedPitch, &d) && d); } else return post->is_fixed_pitch(); } double FontInfo::italic_angle() const { if (_override_italic_angle) return _italic_angle; else if (cff) { double d; (void) cff->dict_value(Efont::Cff::oItalicAngle, &d); return d; } else return post->italic_angle(); } double FontInfo::x_height(const Transform& font_xform) const { if (_override_x_height == x_height_explicit) return _x_height; double x1 = -1, x2 = -1; if (_override_x_height != x_height_os2) // XXX what if 'x', 'm', 'z' were subject to substitution? x1 = char_one_bound(*this, font_xform, 3, false, units_per_em(), (int) 'x', (int) 'm', (int) 'z', 0); if (_override_x_height != x_height_x) try { Efont::OpenType::Os2 os2(otf->table("OS/2")); x2 = (Point(0, os2.x_height()) * font_xform).y; } catch (Efont::OpenType::Bounds) { } static bool warned = false; if (_override_x_height == x_height_auto && x1 >= 0 && x2 >= 0 && fabs(x1 - x2) > units_per_em() / 50.) { if (!warned) { ErrorHandler* errh = ErrorHandler::default_handler(); errh->warning("font x-height and height of % differ by %d%%", (int) (fabs(x1 - x2) * 100 / units_per_em())); errh->message("(The height of % is usually more reliable than the x-height, so I%,m\nusing that. Or try --use-x-height or --no-use-x-height.)\n"); warned = true; } return x1; } else return x2 >= 0 ? x2 : x1; } /* */ Secondary::~Secondary() { } bool Secondary::encode_uni(int code, PermString name, const uint32_t* uni_begin, const uint32_t* uni_end, Metrics &metrics, ErrorHandler *errh) { uint32_t uni = 0; if (uni_begin + 1 == uni_end) uni = *uni_begin; SettingSet set(this, metrics); int max_s = 0; while (uni_begin != uni_end) { int s = setting(*uni_begin, set, errh); if (s == 0) return false; max_s = (max_s > s ? max_s : s); ++uni_begin; set.checkpoint(); } if (uni == U_ALTSELECTOR || (uni >= U_VS1 && uni <= U_VS16) || (uni >= U_VS17 && uni <= U_VS256)) { int selector = 0; if (uni >= U_VS1 && uni <= U_VS16) selector = uni - U_VS1 + 1; else if (uni >= U_VS17 && uni <= U_VS256) selector = uni - U_VS17 + 17; metrics.add_altselector_code(code, selector); name = selector ? permprintf("", selector) : PermString(""); } metrics.encode_virtual(code, name, 0, set.settings(), max_s > 1); return true; } T1Secondary::T1Secondary(const FontInfo &finfo, const String &font_name, const String &otf_file_name) : Secondary(finfo), _font_name(font_name), _otf_file_name(otf_file_name), _units_per_em(finfo.units_per_em()), _xheight((int) ceil(finfo.x_height(Transform()))), _spacewidth(_units_per_em) { double bounds[4], width; if (char_bounds(bounds, width, finfo, Transform(), ' ')) _spacewidth = (int) ceil(width); } int Secondary::setting(uint32_t uni, SettingSet& set, ErrorHandler *errh) { if (_next) return _next->setting(uni, set, errh); else return 0; } SettingSet& SettingSet::show(int uni) { if (!ok_) return *this; int code = metrics_.unicode_encoding(uni); if (code < 0) { Glyph glyph = s_->_finfo.cmap->map_uni(uni); if (glyph != 0) code = metrics_.force_encoding(glyph); } if (code < 0) { ok_ = false; while (v_.size() > original_size_) v_.pop_back(); } else { if (!v_.empty() && v_.back().op == Setting::SHOW && kern_type_) v_.push_back(Setting(kern_type_)); v_.push_back(Setting(Setting::SHOW, code, metrics_.base_glyph(code))); } return *this; } static String dotlessj_file_name; static String dotlessj_dvips_include(const String &, const FontInfo &, ErrorHandler *) { return "<" + pathname_filename(dotlessj_file_name); } int T1Secondary::dotlessj_font(Metrics &metrics, ErrorHandler *errh, Glyph &dj_glyph) { if (!_font_name || !_finfo.otf || !_finfo.cff) return -1; String dj_name; bool install_metrics; // XXX make sure dotlessj is for the main font? if ((dj_name = installed_metrics_font_name(_font_name, "dotlessj"))) install_metrics = false; else { dj_name = suffix_font_name(_font_name, "--lcdfj"); install_metrics = true; } // is dotlessj already mapped? for (int i = 0; i < metrics.n_mapped_fonts(); i++) if (metrics.mapped_font_name(i) == dj_name) return i; if (String filename = installed_type1_dotlessj(_otf_file_name, _finfo.cff->font_name(), (output_flags & G_DOTLESSJ), errh)) { // check for special case: "\0" means the font's "j" is already // dotless if (filename == String("\0", 1)) return J_NODOT; // open dotless-j font file FILE *f = fopen(filename.c_str(), "rb"); if (!f) { errh->error("%s: %s", filename.c_str(), strerror(errno)); return -1; } // read font Efont::Type1Reader *reader; int c = getc(f); ungetc(c, f); if (c == 128) reader = new Efont::Type1PFBReader(f); else reader = new Efont::Type1PFAReader(f); Efont::Type1Font *font = new Efont::Type1Font(*reader); delete reader; if (!font->ok()) { errh->error("%s: no glyphs in dotless-J font", filename.c_str()); delete font; return -1; } // find dotless-J character Vector glyph_names; font->glyph_names(glyph_names); Vector::iterator g = std::find(glyph_names.begin(), glyph_names.end(), "uni0237"); if (g == glyph_names.end()) { errh->error("%s: dotless-J font has no % glyph", filename.c_str()); delete font; return -1; } dj_glyph = g - glyph_names.begin(); // create metrics for dotless-J if (install_metrics) { Metrics dj_metrics(font, 256); dj_metrics.encode('j', U_DOTLESSJ, dj_glyph); ::dotlessj_file_name = filename; output_metrics(dj_metrics, font->font_name(), -1, _finfo, String(), String(), dj_name, dotlessj_dvips_include, errh); } else if (verbose) errh->message("using %<%s%> for dotless-J font metrics", dj_name.c_str()); // add font to metrics return metrics.add_mapped_font(font, dj_name); } else return -1; } int T1Secondary::setting(uint32_t uni, SettingSet& set, ErrorHandler *errh) { Transform xform; extern int letterspace; if (set.show(uni).check()) return 1; switch (uni) { case U_CWM: case U_ALTSELECTOR: set.push_back(Setting::RULE, 0, _xheight); return 1; case U_CAPITALCWM: set.push_back(Setting::RULE, 0, font_cap_height(_finfo, xform)); return 1; case U_ASCENDERCWM: set.push_back(Setting::RULE, 0, font_ascender(_finfo, xform)); return 1; case U_VISIBLESPACE: { int sb = (int) (0.050 * _units_per_em), h = (int) (0.150 * _units_per_em), lw = (int) (0.040 * _units_per_em); set.move(sb, -h); set.push_back(Setting::RULE, lw, h); set.push_back(Setting::RULE, _spacewidth, lw); set.push_back(Setting::RULE, lw, h); set.move(sb, h); return 2; } case U_SS: if (set.show('S').show('S').check()) return 1; break; case U_SSSMALL: if (set.show(U_SSMALL).show(U_SSMALL).check() || set.show('s').show('s').check()) return 1; break; case U_FFSMALL: if (set.show(U_FSMALL).show(U_FSMALL).check() || set.show('f').show('f').check()) return 1; break; case U_FISMALL: if (set.show(U_FSMALL).show(U_ISMALL).check() || set.show('f').show('i').check()) return 1; break; case U_FLSMALL: if (set.show(U_FSMALL).show(U_LSMALL).check() || set.show('f').show('l').check()) return 1; break; case U_FFISMALL: if (set.show(U_FSMALL).show(U_FSMALL).show(U_ISMALL).check() || set.show('f').show('f').show('i').check()) return 1; break; case U_FFLSMALL: if (set.show(U_FSMALL).show(U_FSMALL).show(U_LSMALL).check() || set.show('f').show('f').show('l').check()) return 1; break; case U_IJ: if (set.show('I').show('J').check()) return 1; break; case U_ij: if (set.show('i').show('j').check()) return 1; break; case U_DOTLESSJ: case U_DOTLESSJ_2: case U_MATHDOTLESSJ: { Glyph dj_glyph; int which = dotlessj_font(set.metrics(), errh, dj_glyph); if (which >= 0) { set.push_back(Setting::FONT, which); set.push_back(Setting::SHOW, 'j', dj_glyph); return 2; } else if (which == J_NODOT && set.show('j').check()) return 1; break; } case U_DBLBRACKETLEFT: if (set.show('[').check()) { if (!_finfo.is_fixed_pitch()) { double d = char_one_bound(_finfo, xform, 4, true, 0, '[', 0); set.move((int) (-0.666 * d - letterspace)); } set.show('['); return 1; } break; case U_DBLBRACKETRIGHT: if (set.show(']').check()) { if (!_finfo.is_fixed_pitch()) { double d = char_one_bound(_finfo, xform, 4, true, 0, ']', 0); set.move((int) (-0.666 * d - letterspace)); } set.show(']'); return 1; } break; case U_BARDBL: if (set.show('|').check()) { if (!_finfo.is_fixed_pitch()) { double d = char_one_bound(_finfo, Transform(), 4, true, 0, '|', 0); set.move((int) (-0.333 * d - letterspace)); } set.show('|'); return 1; } break; case U_ASTERISKMATH: { double bounds[5]; double dropdown = 0; if (char_bounds(bounds, bounds[4], _finfo, xform, '*')) dropdown += std::max(bounds[3], 0.) + std::min(bounds[1], 0.); if (char_bounds(bounds, bounds[4], _finfo, xform, '(')) dropdown -= std::max(bounds[3], 0.) + std::min(bounds[1], 0.); int dy = (int) (-dropdown / 2); if (set.move(0, dy).show('*').move(0, -dy).check()) return 1; break; } case U_TWELVEUDASH: if (set.show(U_ENDASH).check()) { if (!_finfo.is_fixed_pitch()) { double d = char_one_bound(_finfo, xform, 4, true, 0, U_ENDASH, 0); set.move((int) (_units_per_em * 0.667 - 2 * d - letterspace)); } set.show(U_ENDASH); return 1; } break; case U_THREEQUARTERSEMDASH: if (set.show(U_ENDASH).check()) { if (!_finfo.is_fixed_pitch()) { double d = char_one_bound(_finfo, xform, 4, true, 0, U_ENDASH, 0); set.move((int) (_units_per_em * 0.750 - 2 * d - letterspace)); } set.show(U_ENDASH); return 1; } break; case U_CENTIGRADE: // TODO: set italic correction to that of a 'C' if (set.show(U_DEGREE).kernx(true).show('C').kernx(false).check()) return 1; break; case U_INTERROBANG: { double exclam_offset = (char_one_bound(_finfo, xform, 4, true, 0, '?', 0) - char_one_bound(_finfo, xform, 4, true, 0, '!', 0)) * 0.5 + 0.050 * _units_per_em; if (set.push_back(Setting::PUSH).move((int) exclam_offset) .show('!').push_back(Setting::POP).show('?').check()) return 1; break; } case U_INTERROBANGDOWN: { double exclam_offset = (char_one_bound(_finfo, xform, 4, true, 0, U_QUESTIONDOWN, 0) - char_one_bound(_finfo, xform, 4, true, 0, U_EXCLAMDOWN, 0)) * 0.5 + 0.050 * _units_per_em; if (set.push_back(Setting::PUSH).move((int) exclam_offset) .show(U_EXCLAMDOWN).push_back(Setting::POP).show(U_QUESTIONDOWN).check()) return 1; break; } case U_PERTENTHOUSAND: if (set.show(0xF661).kernx(true).show(U_FRACTION) .show(0xF655).show(0xF655).show(0xF655).kernx(false).check()) return 1; break; case U_RINGFITTED: { int A_width = char_one_bound(_finfo, xform, 4, true, -_units_per_em, 'A', 0); uint32_t ring_char = U_RINGABOVE; int ring_width = char_one_bound(_finfo, xform, 4, true, -_units_per_em, ring_char, 0); if (ring_width <= -_units_per_em) { ring_char = U_COMBININGRINGABOVE; ring_width = char_one_bound(_finfo, xform, 4, true, -_units_per_em, ring_char, 0); } if (A_width > -_units_per_em && ring_width > -_units_per_em) { int offset = (A_width - ring_width) / 2; if (set.move(offset).show(ring_char).move(A_width - ring_width - offset).check()) { return 1; } } break; } } // variant selectors get the same setting as ALTSELECTOR if ((uni >= U_VS1 && uni <= U_VS16) || (uni >= U_VS17 && uni <= U_VS256)) return setting(U_ALTSELECTOR, set, errh); // otherwise, try other secondaries return Secondary::setting(uni, set, errh); } bool char_bounds(double bounds[4], double& width, const FontInfo &finfo, const Transform &transform, uint32_t uni) { if (Efont::OpenType::Glyph g = finfo.cmap->map_uni(uni)) return Efont::CharstringBounds::bounds(transform, finfo.program()->glyph_context(g), bounds, width); else return false; } double char_one_bound(const FontInfo &finfo, const Transform &transform, int dimen, bool max, double best, int uni, ...) { double bounds[5]; va_list val; va_start(val, uni); while (uni != 0) { if (char_bounds(bounds, bounds[4], finfo, transform, uni)) if (max ? bounds[dimen] > best : bounds[dimen] < best) best = bounds[dimen]; uni = va_arg(val, int); } va_end(val); return best; } double font_cap_height(const FontInfo &finfo, const Transform &font_xform) { try { Efont::OpenType::Os2 os2(finfo.otf->table("OS/2")); return os2.cap_height(); } catch (Efont::OpenType::Bounds) { // XXX what if 'H', 'O', 'B' were subject to substitution? return char_one_bound(finfo, font_xform, 3, false, finfo.units_per_em(), (int) 'H', (int) 'O', (int) 'B', 0); } } double font_ascender(const FontInfo &finfo, const Transform &font_xform) { try { Efont::OpenType::Os2 os2(finfo.otf->table("OS/2")); return os2.typo_ascender(); } catch (Efont::OpenType::Bounds) { // XXX what if 'd', 'l' were subject to substitution? return char_one_bound(finfo, font_xform, 3, true, finfo.x_height(font_xform), (int) 'd', (int) 'l', 0); } } lcdf-typetools-2.108/otftotfm/util.hh0000644000175000017500000000211713423375330014561 00000000000000#ifndef OTFTOTFM_UTIL_HH #define OTFTOTFM_UTIL_HH #include #include #include class ErrorHandler; extern bool no_create; extern bool verbose; extern bool force; enum { G_ENCODING = 1, G_METRICS = 2, G_VMETRICS = 4, G_TYPE1 = 8, G_PSFONTSMAP = 16, G_BINARY = 32, G_ASCII = 64, G_DOTLESSJ = 128, G_UPDMAP = 256, G_TRUETYPE = 512, G_TYPE42 = 1024, G_UPDMAP_USER = 2048 }; extern unsigned output_flags; String read_file(String filename, ErrorHandler *, bool warn = false); String printable_filename(const String &); String pathname_filename(const String &); bool same_filename(const String &a, const String &b); String shell_quote(const String &); int temporary_file(String &, ErrorHandler *); int mysystem(const char *command, ErrorHandler *); FILE* mypopen(const char* command, const char* type, ErrorHandler* errh); bool parse_unicode_number(const char*, const char*, int require_prefix, uint32_t& result); #ifdef WIN32 #define WEXITSTATUS(es) (es) #endif template void ignore_result(T result) { (void) result; } #endif lcdf-typetools-2.108/otftotfm/otftotfm.hh0000644000175000017500000000145213423375330015447 00000000000000#ifndef OTFTOTFM_OTFTOTFM_HH #define OTFTOTFM_OTFTOTFM_HH #include class Metrics; class FontInfo; class StringAccum; class ErrorHandler; String suffix_font_name(const String &font_name, const String &suffix); String installed_metrics_font_name(const String &font_name, const String &secondary); void output_metrics(Metrics &metrics, const String &ps_name, int boundary_char, const FontInfo &finfo, const String &encoding_name, const String &encoding_file, const String &font_name, String (*dvips_include)(const String &ps_name, const FontInfo &, ErrorHandler *), ErrorHandler *errh); double font_cap_height(const FontInfo &, const Transform &); double font_ascender(const FontInfo &, const Transform &); double font_slant(const FontInfo &); #endif lcdf-typetools-2.108/otftotfm/uniprop.cc0000644000175000017500000011341513423375330015272 00000000000000/* uniprop.{cc,hh} -- code for Unicode character properties * * Copyright (c) 2004-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #include #include "uniprop.hh" #include const unsigned char UnicodeProperty::property_pages[] = { 0, P_Cn, 0, P_Cc, 32, P_Zs, 33, P_Po, 36, P_Sc, 37, P_Po, 40, P_Ps, 41, P_Pe, 42, P_Po, 43, P_Sm, 44, P_Po, 45, P_Pd, 46, P_Po, 48, P_Nd, 58, P_Po, 60, P_Sm, 63, P_Po, 65, P_Lu, 91, P_Ps, 92, P_Po, 93, P_Pe, 94, P_Sk, 95, P_Pc, 96, P_Sk, 97, P_Ll, 123, P_Ps, 124, P_Sm, 125, P_Pe, 126, P_Sm, 127, P_Cc, 160, P_Zs, 161, P_Po, 162, P_Sc, 166, P_So, 167, P_Po, 168, P_Sk, 169, P_So, 170, P_Lo, 171, P_Pi, 172, P_Sm, 173, P_Cf, 174, P_So, 175, P_Sk, 176, P_So, 177, P_Sm, 178, P_No, 180, P_Sk, 181, P_Ll, 182, P_Po, 184, P_Sk, 185, P_No, 186, P_Lo, 187, P_Pf, 188, P_No, 191, P_Po, 192, P_Lu, 215, P_Sm, 216, P_Lu, 223, P_Ll, 247, P_Sm, 248, P_Ll, 0, P_Lul, 56, P_Ll, 57, P_Lul, 73, P_Ll, 74, P_Lul, 120, P_Lu, 122, P_Ll, 123, P_Lul, 127, P_Ll, 129, P_Lu, 131, P_Ll, 132, P_Lul, 134, P_Lu, 136, P_Ll, 137, P_Lu, 140, P_Ll, 142, P_Lu, 146, P_Ll, 147, P_Lu, 149, P_Ll, 150, P_Lu, 153, P_Ll, 156, P_Lu, 158, P_Ll, 159, P_Lu, 161, P_Ll, 162, P_Lul, 166, P_Lu, 168, P_Ll, 169, P_Lul, 171, P_Ll, 172, P_Lul, 174, P_Lu, 176, P_Ll, 177, P_Lu, 180, P_Ll, 181, P_Lul, 183, P_Lu, 185, P_Ll, 187, P_Lo, 188, P_Lul, 190, P_Ll, 192, P_Lo, 196, P_Lu, 197, P_Lt, 198, P_Ll, 199, P_Lu, 200, P_Lt, 201, P_Ll, 202, P_Lu, 203, P_Lt, 204, P_Ll, 205, P_Lul, 221, P_Ll, 222, P_Lul, 240, P_Ll, 241, P_Lu, 242, P_Lt, 243, P_Ll, 244, P_Lul, 246, P_Lu, 249, P_Ll, 250, P_Lul, 0, P_Lul, 52, P_Ll, 58, P_Lu, 60, P_Ll, 61, P_Lu, 63, P_Ll, 65, P_Lul, 67, P_Lu, 71, P_Ll, 72, P_Lul, 80, P_Ll, 148, P_Lo, 149, P_Ll, 176, P_Lm, 194, P_Sk, 198, P_Lm, 210, P_Sk, 224, P_Lm, 229, P_Sk, 236, P_Lm, 237, P_Sk, 238, P_Lm, 239, P_Sk, 0, P_Mn, 112, P_Lul, 116, P_Lm, 117, P_Sk, 118, P_Lul, 120, P_Cn, 122, P_Lm, 123, P_Ll, 126, P_Po, 127, P_Lu, 128, P_Cn, 132, P_Sk, 134, P_Lu, 135, P_Po, 136, P_Lu, 139, P_Cn, 140, P_Lu, 141, P_Cn, 142, P_Lu, 144, P_Ll, 145, P_Lu, 162, P_Cn, 163, P_Lu, 172, P_Ll, 207, P_Lul, 209, P_Ll, 210, P_Lu, 213, P_Ll, 216, P_Lul, 240, P_Ll, 244, P_Lul, 246, P_Sm, 247, P_Lul, 249, P_Lu, 251, P_Ll, 253, P_Lu, 0, P_Lu, 48, P_Ll, 96, P_Lul, 130, P_So, 131, P_Mn, 136, P_Me, 138, P_Lul, 192, P_Lu, 194, P_Ll, 195, P_Lul, 207, P_Ll, 208, P_Lul, 0, P_Lul, 48, P_Cn, 49, P_Lu, 87, P_Cn, 89, P_Lm, 90, P_Po, 96, P_Cn, 97, P_Ll, 136, P_Cn, 137, P_Po, 138, P_Pd, 139, P_Cn, 141, P_So, 143, P_Sc, 144, P_Cn, 145, P_Mn, 190, P_Pd, 191, P_Mn, 192, P_Po, 193, P_Mn, 195, P_Po, 196, P_Mn, 198, P_Po, 199, P_Mn, 200, P_Cn, 208, P_Lo, 235, P_Cn, 240, P_Lo, 243, P_Po, 245, P_Cn, 0, P_Cf, 6, P_Sm, 9, P_Po, 11, P_Sc, 12, P_Po, 14, P_So, 16, P_Mn, 27, P_Po, 28, P_Cf, 29, P_Cn, 30, P_Po, 32, P_Lo, 64, P_Lm, 65, P_Lo, 75, P_Mn, 96, P_Nd, 106, P_Po, 110, P_Lo, 112, P_Mn, 113, P_Lo, 212, P_Po, 213, P_Lo, 214, P_Mn, 221, P_Cf, 222, P_So, 223, P_Mn, 229, P_Lm, 231, P_Mn, 233, P_So, 234, P_Mn, 238, P_Lo, 240, P_Nd, 250, P_Lo, 253, P_So, 255, P_Lo, 0, P_Po, 14, P_Cn, 15, P_Cf, 16, P_Lo, 17, P_Mn, 18, P_Lo, 48, P_Mn, 75, P_Cn, 77, P_Lo, 166, P_Mn, 177, P_Lo, 178, P_Cn, 192, P_Nd, 202, P_Lo, 235, P_Mn, 244, P_Lm, 246, P_So, 247, P_Po, 250, P_Lm, 251, P_Cn, 0, P_Lo, 22, P_Mn, 26, P_Lm, 27, P_Mn, 36, P_Lm, 37, P_Mn, 40, P_Lm, 41, P_Mn, 46, P_Cn, 48, P_Po, 63, P_Cn, 64, P_Lo, 89, P_Mn, 92, P_Cn, 94, P_Po, 95, P_Cn, 160, P_Lo, 181, P_Cn, 182, P_Lo, 190, P_Cn, 212, P_Mn, 226, P_Cf, 227, P_Mn, 0, P_Mn, 3, P_Mc, 4, P_Lo, 58, P_Mn, 59, P_Mc, 60, P_Mn, 61, P_Lo, 62, P_Mc, 65, P_Mn, 73, P_Mc, 77, P_Mn, 78, P_Mc, 80, P_Lo, 81, P_Mn, 88, P_Lo, 98, P_Mn, 100, P_Po, 102, P_Nd, 112, P_Po, 113, P_Lm, 114, P_Lo, 129, P_Mn, 130, P_Mc, 132, P_Cn, 133, P_Lo, 141, P_Cn, 143, P_Lo, 145, P_Cn, 147, P_Lo, 169, P_Cn, 170, P_Lo, 177, P_Cn, 178, P_Lo, 179, P_Cn, 182, P_Lo, 186, P_Cn, 188, P_Mn, 189, P_Lo, 190, P_Mc, 193, P_Mn, 197, P_Cn, 199, P_Mc, 201, P_Cn, 203, P_Mc, 205, P_Mn, 206, P_Lo, 207, P_Cn, 215, P_Mc, 216, P_Cn, 220, P_Lo, 222, P_Cn, 223, P_Lo, 226, P_Mn, 228, P_Cn, 230, P_Nd, 240, P_Lo, 242, P_Sc, 244, P_No, 250, P_So, 251, P_Sc, 252, P_Cn, 0, P_Cn, 1, P_Mn, 3, P_Mc, 4, P_Cn, 5, P_Lo, 11, P_Cn, 15, P_Lo, 17, P_Cn, 19, P_Lo, 41, P_Cn, 42, P_Lo, 49, P_Cn, 50, P_Lo, 52, P_Cn, 53, P_Lo, 55, P_Cn, 56, P_Lo, 58, P_Cn, 60, P_Mn, 61, P_Cn, 62, P_Mc, 65, P_Mn, 67, P_Cn, 71, P_Mn, 73, P_Cn, 75, P_Mn, 78, P_Cn, 81, P_Mn, 82, P_Cn, 89, P_Lo, 93, P_Cn, 94, P_Lo, 95, P_Cn, 102, P_Nd, 112, P_Mn, 114, P_Lo, 117, P_Mn, 118, P_Cn, 129, P_Mn, 131, P_Mc, 132, P_Cn, 133, P_Lo, 142, P_Cn, 143, P_Lo, 146, P_Cn, 147, P_Lo, 169, P_Cn, 170, P_Lo, 177, P_Cn, 178, P_Lo, 180, P_Cn, 181, P_Lo, 186, P_Cn, 188, P_Mn, 189, P_Lo, 190, P_Mc, 193, P_Mn, 198, P_Cn, 199, P_Mn, 201, P_Mc, 202, P_Cn, 203, P_Mc, 205, P_Mn, 206, P_Cn, 208, P_Lo, 209, P_Cn, 224, P_Lo, 226, P_Mn, 228, P_Cn, 230, P_Nd, 240, P_Po, 241, P_Sc, 242, P_Cn, 249, P_Lo, 250, P_Cn, 0, P_Cn, 1, P_Mn, 2, P_Mc, 4, P_Cn, 5, P_Lo, 13, P_Cn, 15, P_Lo, 17, P_Cn, 19, P_Lo, 41, P_Cn, 42, P_Lo, 49, P_Cn, 50, P_Lo, 52, P_Cn, 53, P_Lo, 58, P_Cn, 60, P_Mn, 61, P_Lo, 62, P_Mc, 63, P_Mn, 64, P_Mc, 65, P_Mn, 69, P_Cn, 71, P_Mc, 73, P_Cn, 75, P_Mc, 77, P_Mn, 78, P_Cn, 86, P_Mn, 87, P_Mc, 88, P_Cn, 92, P_Lo, 94, P_Cn, 95, P_Lo, 98, P_Mn, 100, P_Cn, 102, P_Nd, 112, P_So, 113, P_Lo, 114, P_No, 120, P_Cn, 130, P_Mn, 131, P_Lo, 132, P_Cn, 133, P_Lo, 139, P_Cn, 142, P_Lo, 145, P_Cn, 146, P_Lo, 150, P_Cn, 153, P_Lo, 155, P_Cn, 156, P_Lo, 157, P_Cn, 158, P_Lo, 160, P_Cn, 163, P_Lo, 165, P_Cn, 168, P_Lo, 171, P_Cn, 174, P_Lo, 186, P_Cn, 190, P_Mc, 192, P_Mn, 193, P_Mc, 195, P_Cn, 198, P_Mc, 201, P_Cn, 202, P_Mc, 205, P_Mn, 206, P_Cn, 208, P_Lo, 209, P_Cn, 215, P_Mc, 216, P_Cn, 230, P_Nd, 240, P_No, 243, P_So, 249, P_Sc, 250, P_So, 251, P_Cn, 0, P_Mn, 1, P_Mc, 4, P_Cn, 5, P_Lo, 13, P_Cn, 14, P_Lo, 17, P_Cn, 18, P_Lo, 41, P_Cn, 42, P_Lo, 58, P_Cn, 61, P_Lo, 62, P_Mn, 65, P_Mc, 69, P_Cn, 70, P_Mn, 73, P_Cn, 74, P_Mn, 78, P_Cn, 85, P_Mn, 87, P_Cn, 88, P_Lo, 91, P_Cn, 96, P_Lo, 98, P_Mn, 100, P_Cn, 102, P_Nd, 112, P_Cn, 120, P_No, 127, P_So, 128, P_Lo, 129, P_Mn, 130, P_Mc, 132, P_Cn, 133, P_Lo, 141, P_Cn, 142, P_Lo, 145, P_Cn, 146, P_Lo, 169, P_Cn, 170, P_Lo, 180, P_Cn, 181, P_Lo, 186, P_Cn, 188, P_Mn, 189, P_Lo, 190, P_Mc, 191, P_Mn, 192, P_Mc, 197, P_Cn, 198, P_Mn, 199, P_Mc, 201, P_Cn, 202, P_Mc, 204, P_Mn, 206, P_Cn, 213, P_Mc, 215, P_Cn, 222, P_Lo, 223, P_Cn, 224, P_Lo, 226, P_Mn, 228, P_Cn, 230, P_Nd, 240, P_Cn, 241, P_Lo, 243, P_Cn, 0, P_Cn, 1, P_Mn, 2, P_Mc, 4, P_Cn, 5, P_Lo, 13, P_Cn, 14, P_Lo, 17, P_Cn, 18, P_Lo, 59, P_Cn, 61, P_Lo, 62, P_Mc, 65, P_Mn, 69, P_Cn, 70, P_Mc, 73, P_Cn, 74, P_Mc, 77, P_Mn, 78, P_Lo, 79, P_So, 80, P_Cn, 84, P_Lo, 87, P_Mc, 88, P_No, 95, P_Lo, 98, P_Mn, 100, P_Cn, 102, P_Nd, 112, P_No, 121, P_So, 122, P_Lo, 128, P_Cn, 130, P_Mc, 132, P_Cn, 133, P_Lo, 151, P_Cn, 154, P_Lo, 178, P_Cn, 179, P_Lo, 188, P_Cn, 189, P_Lo, 190, P_Cn, 192, P_Lo, 199, P_Cn, 202, P_Mn, 203, P_Cn, 207, P_Mc, 210, P_Mn, 213, P_Cn, 214, P_Mn, 215, P_Cn, 216, P_Mc, 224, P_Cn, 230, P_Nd, 240, P_Cn, 242, P_Mc, 244, P_Po, 245, P_Cn, 0, P_Cn, 1, P_Lo, 49, P_Mn, 50, P_Lo, 52, P_Mn, 59, P_Cn, 63, P_Sc, 64, P_Lo, 70, P_Lm, 71, P_Mn, 79, P_Po, 80, P_Nd, 90, P_Po, 92, P_Cn, 129, P_Lo, 131, P_Cn, 132, P_Lo, 133, P_Cn, 135, P_Lo, 137, P_Cn, 138, P_Lo, 139, P_Cn, 141, P_Lo, 142, P_Cn, 148, P_Lo, 152, P_Cn, 153, P_Lo, 160, P_Cn, 161, P_Lo, 164, P_Cn, 165, P_Lo, 166, P_Cn, 167, P_Lo, 168, P_Cn, 170, P_Lo, 172, P_Cn, 173, P_Lo, 177, P_Mn, 178, P_Lo, 180, P_Mn, 186, P_Cn, 187, P_Mn, 189, P_Lo, 190, P_Cn, 192, P_Lo, 197, P_Cn, 198, P_Lm, 199, P_Cn, 200, P_Mn, 206, P_Cn, 208, P_Nd, 218, P_Cn, 220, P_Lo, 224, P_Cn, 0, P_Lo, 1, P_So, 4, P_Po, 19, P_So, 20, P_Po, 21, P_So, 24, P_Mn, 26, P_So, 32, P_Nd, 42, P_No, 52, P_So, 53, P_Mn, 54, P_So, 55, P_Mn, 56, P_So, 57, P_Mn, 58, P_Ps, 59, P_Pe, 60, P_Ps, 61, P_Pe, 62, P_Mc, 64, P_Lo, 72, P_Cn, 73, P_Lo, 109, P_Cn, 113, P_Mn, 127, P_Mc, 128, P_Mn, 133, P_Po, 134, P_Mn, 136, P_Lo, 141, P_Mn, 152, P_Cn, 153, P_Mn, 189, P_Cn, 190, P_So, 198, P_Mn, 199, P_So, 205, P_Cn, 206, P_So, 208, P_Po, 213, P_So, 217, P_Po, 219, P_Cn, 0, P_Lo, 43, P_Mc, 45, P_Mn, 49, P_Mc, 50, P_Mn, 56, P_Mc, 57, P_Mn, 59, P_Mc, 61, P_Mn, 63, P_Lo, 64, P_Nd, 74, P_Po, 80, P_Lo, 86, P_Mc, 88, P_Mn, 90, P_Lo, 94, P_Mn, 97, P_Lo, 98, P_Mc, 101, P_Lo, 103, P_Mc, 110, P_Lo, 113, P_Mn, 117, P_Lo, 130, P_Mn, 131, P_Mc, 133, P_Mn, 135, P_Mc, 141, P_Mn, 142, P_Lo, 143, P_Mc, 144, P_Nd, 154, P_Mc, 157, P_Mn, 158, P_So, 160, P_Lu, 198, P_Cn, 199, P_Lu, 200, P_Cn, 205, P_Lu, 206, P_Cn, 208, P_Lo, 251, P_Po, 252, P_Lm, 253, P_Lo, 0, P_Lo, 0, P_Lo, 73, P_Cn, 74, P_Lo, 78, P_Cn, 80, P_Lo, 87, P_Cn, 88, P_Lo, 89, P_Cn, 90, P_Lo, 94, P_Cn, 96, P_Lo, 137, P_Cn, 138, P_Lo, 142, P_Cn, 144, P_Lo, 177, P_Cn, 178, P_Lo, 182, P_Cn, 184, P_Lo, 191, P_Cn, 192, P_Lo, 193, P_Cn, 194, P_Lo, 198, P_Cn, 200, P_Lo, 215, P_Cn, 216, P_Lo, 0, P_Lo, 17, P_Cn, 18, P_Lo, 22, P_Cn, 24, P_Lo, 91, P_Cn, 93, P_Mn, 96, P_Po, 105, P_No, 125, P_Cn, 128, P_Lo, 144, P_So, 154, P_Cn, 160, P_Lu, 246, P_Cn, 248, P_Ll, 254, P_Cn, 0, P_Pd, 1, P_Lo, 0, P_Lo, 109, P_Po, 111, P_Lo, 128, P_Zs, 129, P_Lo, 155, P_Ps, 156, P_Pe, 157, P_Cn, 160, P_Lo, 235, P_Po, 238, P_Nl, 241, P_Lo, 249, P_Cn, 0, P_Lo, 13, P_Cn, 14, P_Lo, 18, P_Mn, 21, P_Cn, 32, P_Lo, 50, P_Mn, 53, P_Po, 55, P_Cn, 64, P_Lo, 82, P_Mn, 84, P_Cn, 96, P_Lo, 109, P_Cn, 110, P_Lo, 113, P_Cn, 114, P_Mn, 116, P_Cn, 128, P_Lo, 180, P_Mn, 182, P_Mc, 183, P_Mn, 190, P_Mc, 198, P_Mn, 199, P_Mc, 201, P_Mn, 212, P_Po, 215, P_Lm, 216, P_Po, 219, P_Sc, 220, P_Lo, 221, P_Mn, 222, P_Cn, 224, P_Nd, 234, P_Cn, 240, P_No, 250, P_Cn, 0, P_Po, 6, P_Pd, 7, P_Po, 11, P_Mn, 14, P_Cf, 15, P_Cn, 16, P_Nd, 26, P_Cn, 32, P_Lo, 67, P_Lm, 68, P_Lo, 120, P_Cn, 128, P_Lo, 133, P_Mn, 135, P_Lo, 169, P_Mn, 170, P_Lo, 171, P_Cn, 176, P_Lo, 246, P_Cn, 0, P_Lo, 31, P_Cn, 32, P_Mn, 35, P_Mc, 39, P_Mn, 41, P_Mc, 44, P_Cn, 48, P_Mc, 50, P_Mn, 51, P_Mc, 57, P_Mn, 60, P_Cn, 64, P_So, 65, P_Cn, 68, P_Po, 70, P_Nd, 80, P_Lo, 110, P_Cn, 112, P_Lo, 117, P_Cn, 128, P_Lo, 172, P_Cn, 176, P_Lo, 202, P_Cn, 208, P_Nd, 218, P_No, 219, P_Cn, 222, P_So, 0, P_Lo, 23, P_Mn, 25, P_Mc, 27, P_Mn, 28, P_Cn, 30, P_Po, 32, P_Lo, 85, P_Mc, 86, P_Mn, 87, P_Mc, 88, P_Mn, 95, P_Cn, 96, P_Mn, 97, P_Mc, 98, P_Mn, 99, P_Mc, 101, P_Mn, 109, P_Mc, 115, P_Mn, 125, P_Cn, 127, P_Mn, 128, P_Nd, 138, P_Cn, 144, P_Nd, 154, P_Cn, 160, P_Po, 167, P_Lm, 168, P_Po, 174, P_Cn, 176, P_Mn, 190, P_Me, 191, P_Cn, 0, P_Mn, 4, P_Mc, 5, P_Lo, 52, P_Mn, 53, P_Mc, 54, P_Mn, 59, P_Mc, 60, P_Mn, 61, P_Mc, 66, P_Mn, 67, P_Mc, 69, P_Lo, 76, P_Cn, 80, P_Nd, 90, P_Po, 97, P_So, 107, P_Mn, 116, P_So, 125, P_Cn, 128, P_Mn, 130, P_Mc, 131, P_Lo, 161, P_Mc, 162, P_Mn, 166, P_Mc, 168, P_Mn, 170, P_Mc, 171, P_Mn, 174, P_Lo, 176, P_Nd, 186, P_Lo, 230, P_Mn, 231, P_Mc, 232, P_Mn, 234, P_Mc, 237, P_Mn, 238, P_Mc, 239, P_Mn, 242, P_Mc, 244, P_Cn, 252, P_Po, 0, P_Lo, 36, P_Mc, 44, P_Mn, 52, P_Mc, 54, P_Mn, 56, P_Cn, 59, P_Po, 64, P_Nd, 74, P_Cn, 77, P_Lo, 80, P_Nd, 90, P_Lo, 120, P_Lm, 126, P_Po, 128, P_Ll, 137, P_Cn, 192, P_Po, 200, P_Cn, 208, P_Mn, 211, P_Po, 212, P_Mn, 225, P_Mc, 226, P_Mn, 233, P_Lo, 237, P_Mn, 238, P_Lo, 242, P_Mc, 244, P_Mn, 245, P_Lo, 247, P_Cn, 248, P_Mn, 250, P_Cn, 0, P_Ll, 44, P_Lm, 107, P_Ll, 120, P_Lm, 121, P_Ll, 155, P_Lm, 192, P_Mn, 246, P_Cn, 251, P_Mn, 0, P_Lul, 150, P_Ll, 158, P_Lul, 0, P_Ll, 8, P_Lu, 16, P_Ll, 22, P_Cn, 24, P_Lu, 30, P_Cn, 32, P_Ll, 40, P_Lu, 48, P_Ll, 56, P_Lu, 64, P_Ll, 70, P_Cn, 72, P_Lu, 78, P_Cn, 80, P_Ll, 88, P_Cn, 89, P_Lu, 90, P_Cn, 91, P_Lu, 92, P_Cn, 93, P_Lu, 94, P_Cn, 95, P_Lul, 97, P_Ll, 104, P_Lu, 112, P_Ll, 126, P_Cn, 128, P_Ll, 136, P_Lt, 144, P_Ll, 152, P_Lt, 160, P_Ll, 168, P_Lt, 176, P_Ll, 181, P_Cn, 182, P_Ll, 184, P_Lu, 188, P_Lt, 189, P_Sk, 190, P_Ll, 191, P_Sk, 194, P_Ll, 197, P_Cn, 198, P_Ll, 200, P_Lu, 204, P_Lt, 205, P_Sk, 208, P_Ll, 212, P_Cn, 214, P_Ll, 216, P_Lu, 220, P_Cn, 221, P_Sk, 224, P_Ll, 232, P_Lu, 237, P_Sk, 240, P_Cn, 242, P_Ll, 245, P_Cn, 246, P_Ll, 248, P_Lu, 252, P_Lt, 253, P_Sk, 255, P_Cn, 0, P_Zs, 11, P_Cf, 16, P_Pd, 22, P_Po, 24, P_Pi, 25, P_Pf, 26, P_Ps, 27, P_Pi, 29, P_Pf, 30, P_Ps, 31, P_Pi, 32, P_Po, 40, P_Zl, 41, P_Zp, 42, P_Cf, 47, P_Zs, 48, P_Po, 57, P_Pi, 58, P_Pf, 59, P_Po, 63, P_Pc, 65, P_Po, 68, P_Sm, 69, P_Ps, 70, P_Pe, 71, P_Po, 82, P_Sm, 83, P_Po, 84, P_Pc, 85, P_Po, 95, P_Zs, 96, P_Cf, 101, P_Cn, 102, P_Cf, 112, P_No, 113, P_Lm, 114, P_Cn, 116, P_No, 122, P_Sm, 125, P_Ps, 126, P_Pe, 127, P_Lm, 128, P_No, 138, P_Sm, 141, P_Ps, 142, P_Pe, 143, P_Cn, 144, P_Lm, 157, P_Cn, 160, P_Sc, 191, P_Cn, 208, P_Mn, 221, P_Me, 225, P_Mn, 226, P_Me, 229, P_Mn, 241, P_Cn, 0, P_So, 2, P_Lu, 3, P_So, 7, P_Lu, 8, P_So, 10, P_Ll, 11, P_Lu, 14, P_Ll, 16, P_Lu, 19, P_Ll, 20, P_So, 21, P_Lu, 22, P_So, 24, P_Sm, 25, P_Lu, 30, P_So, 36, P_Lu, 37, P_So, 38, P_Lu, 39, P_So, 40, P_Lu, 41, P_So, 42, P_Lu, 46, P_So, 47, P_Ll, 48, P_Lu, 52, P_Ll, 53, P_Lo, 57, P_Ll, 58, P_So, 60, P_Ll, 62, P_Lu, 64, P_Sm, 69, P_Lul, 71, P_Ll, 74, P_So, 75, P_Sm, 76, P_So, 78, P_Ll, 79, P_So, 80, P_No, 96, P_Nl, 131, P_Lul, 133, P_Nl, 137, P_No, 138, P_So, 140, P_Cn, 144, P_Sm, 149, P_So, 154, P_Sm, 156, P_So, 160, P_Sm, 161, P_So, 163, P_Sm, 164, P_So, 166, P_Sm, 167, P_So, 174, P_Sm, 175, P_So, 206, P_Sm, 208, P_So, 210, P_Sm, 211, P_So, 212, P_Sm, 213, P_So, 244, P_Sm, 0, P_Sm, 0, P_So, 8, P_Ps, 9, P_Pe, 10, P_Ps, 11, P_Pe, 12, P_So, 32, P_Sm, 34, P_So, 41, P_Ps, 42, P_Pe, 43, P_So, 124, P_Sm, 125, P_So, 155, P_Sm, 180, P_So, 220, P_Sm, 226, P_So, 255, P_Cn, 0, P_So, 39, P_Cn, 64, P_So, 75, P_Cn, 96, P_No, 156, P_So, 234, P_No, 0, P_So, 183, P_Sm, 184, P_So, 193, P_Sm, 194, P_So, 248, P_Sm, 0, P_So, 111, P_Sm, 112, P_So, 0, P_So, 104, P_Ps, 105, P_Pe, 106, P_Ps, 107, P_Pe, 108, P_Ps, 109, P_Pe, 110, P_Ps, 111, P_Pe, 112, P_Ps, 113, P_Pe, 114, P_Ps, 115, P_Pe, 116, P_Ps, 117, P_Pe, 118, P_No, 148, P_So, 192, P_Sm, 197, P_Ps, 198, P_Pe, 199, P_Sm, 230, P_Ps, 231, P_Pe, 232, P_Ps, 233, P_Pe, 234, P_Ps, 235, P_Pe, 236, P_Ps, 237, P_Pe, 238, P_Ps, 239, P_Pe, 240, P_Sm, 0, P_So, 0, P_Sm, 131, P_Ps, 132, P_Pe, 133, P_Ps, 134, P_Pe, 135, P_Ps, 136, P_Pe, 137, P_Ps, 138, P_Pe, 139, P_Ps, 140, P_Pe, 141, P_Ps, 142, P_Pe, 143, P_Ps, 144, P_Pe, 145, P_Ps, 146, P_Pe, 147, P_Ps, 148, P_Pe, 149, P_Ps, 150, P_Pe, 151, P_Ps, 152, P_Pe, 153, P_Sm, 216, P_Ps, 217, P_Pe, 218, P_Ps, 219, P_Pe, 220, P_Sm, 252, P_Ps, 253, P_Pe, 254, P_Sm, 0, P_So, 48, P_Sm, 69, P_So, 71, P_Sm, 77, P_So, 116, P_Cn, 118, P_So, 150, P_Cn, 152, P_So, 186, P_Cn, 189, P_So, 201, P_Cn, 202, P_So, 210, P_Cn, 236, P_So, 240, P_Cn, 0, P_Lu, 47, P_Cn, 48, P_Ll, 95, P_Cn, 96, P_Lul, 98, P_Lu, 101, P_Ll, 103, P_Lul, 109, P_Lu, 113, P_Ll, 114, P_Lul, 116, P_Ll, 117, P_Lul, 119, P_Ll, 124, P_Lm, 126, P_Lu, 129, P_Ll, 130, P_Lul, 228, P_Ll, 229, P_So, 235, P_Lul, 239, P_Mn, 242, P_Lul, 244, P_Cn, 249, P_Po, 253, P_No, 254, P_Po, 0, P_Ll, 38, P_Cn, 39, P_Ll, 40, P_Cn, 45, P_Ll, 46, P_Cn, 48, P_Lo, 104, P_Cn, 111, P_Lm, 112, P_Po, 113, P_Cn, 127, P_Mn, 128, P_Lo, 151, P_Cn, 160, P_Lo, 167, P_Cn, 168, P_Lo, 175, P_Cn, 176, P_Lo, 183, P_Cn, 184, P_Lo, 191, P_Cn, 192, P_Lo, 199, P_Cn, 200, P_Lo, 207, P_Cn, 208, P_Lo, 215, P_Cn, 216, P_Lo, 223, P_Cn, 224, P_Mn, 0, P_Po, 2, P_Pi, 3, P_Pf, 4, P_Pi, 5, P_Pf, 6, P_Po, 9, P_Pi, 10, P_Pf, 11, P_Po, 12, P_Pi, 13, P_Pf, 14, P_Po, 23, P_Pd, 24, P_Po, 26, P_Pd, 27, P_Po, 28, P_Pi, 29, P_Pf, 30, P_Po, 32, P_Pi, 33, P_Pf, 34, P_Ps, 35, P_Pe, 36, P_Ps, 37, P_Pe, 38, P_Ps, 39, P_Pe, 40, P_Ps, 41, P_Pe, 42, P_Po, 47, P_Lm, 48, P_Po, 58, P_Pd, 60, P_Po, 64, P_Pd, 65, P_Po, 66, P_Ps, 67, P_Po, 69, P_Cn, 128, P_So, 154, P_Cn, 155, P_So, 244, P_Cn, 0, P_So, 214, P_Cn, 240, P_So, 252, P_Cn, 0, P_Zs, 1, P_Po, 4, P_So, 5, P_Lm, 6, P_Lo, 7, P_Nl, 8, P_Ps, 9, P_Pe, 10, P_Ps, 11, P_Pe, 12, P_Ps, 13, P_Pe, 14, P_Ps, 15, P_Pe, 16, P_Ps, 17, P_Pe, 18, P_So, 20, P_Ps, 21, P_Pe, 22, P_Ps, 23, P_Pe, 24, P_Ps, 25, P_Pe, 26, P_Ps, 27, P_Pe, 28, P_Pd, 29, P_Ps, 30, P_Pe, 32, P_So, 33, P_Nl, 42, P_Mn, 46, P_Mc, 48, P_Pd, 49, P_Lm, 54, P_So, 56, P_Nl, 59, P_Lm, 60, P_Lo, 61, P_Po, 62, P_So, 64, P_Cn, 65, P_Lo, 151, P_Cn, 153, P_Mn, 155, P_Sk, 157, P_Lm, 159, P_Lo, 160, P_Pd, 161, P_Lo, 251, P_Po, 252, P_Lm, 255, P_Lo, 0, P_Cn, 5, P_Lo, 46, P_Cn, 49, P_Lo, 143, P_Cn, 144, P_So, 146, P_No, 150, P_So, 160, P_Lo, 187, P_Cn, 192, P_So, 228, P_Cn, 240, P_Lo, 0, P_So, 31, P_Cn, 32, P_No, 42, P_So, 72, P_No, 80, P_So, 81, P_No, 96, P_So, 128, P_No, 138, P_So, 177, P_No, 192, P_So, 255, P_Cn, 0, P_Lo, 1, P_Cn, 0, P_Cn, 181, P_Lo, 182, P_Cn, 192, P_So, 0, P_Cn, 213, P_Lo, 214, P_Cn, 0, P_Lo, 21, P_Lm, 22, P_Lo, 0, P_Lo, 141, P_Cn, 144, P_So, 199, P_Cn, 208, P_Lo, 248, P_Lm, 254, P_Po, 0, P_Lo, 12, P_Lm, 13, P_Po, 16, P_Lo, 32, P_Nd, 42, P_Lo, 44, P_Cn, 64, P_Lul, 110, P_Lo, 111, P_Mn, 112, P_Me, 115, P_Po, 116, P_Mn, 126, P_Po, 127, P_Lm, 128, P_Lul, 156, P_Lm, 158, P_Mn, 160, P_Lo, 230, P_Nl, 240, P_Mn, 242, P_Po, 248, P_Cn, 0, P_Sk, 23, P_Lm, 32, P_Sk, 34, P_Lul, 48, P_Ll, 50, P_Lul, 112, P_Lm, 113, P_Ll, 121, P_Lul, 125, P_Lu, 127, P_Ll, 128, P_Lul, 136, P_Lm, 137, P_Sk, 139, P_Lul, 143, P_Lo, 144, P_Lul, 148, P_Ll, 150, P_Lul, 170, P_Lu, 175, P_Cn, 176, P_Lu, 181, P_Ll, 182, P_Lul, 184, P_Cn, 247, P_Lo, 248, P_Lm, 250, P_Ll, 251, P_Lo, 0, P_Lo, 2, P_Mn, 3, P_Lo, 6, P_Mn, 7, P_Lo, 11, P_Mn, 12, P_Lo, 35, P_Mc, 37, P_Mn, 39, P_Mc, 40, P_So, 44, P_Cn, 48, P_No, 54, P_So, 56, P_Sc, 57, P_So, 58, P_Cn, 64, P_Lo, 116, P_Po, 120, P_Cn, 128, P_Mc, 130, P_Lo, 180, P_Mc, 196, P_Mn, 198, P_Cn, 206, P_Po, 208, P_Nd, 218, P_Cn, 224, P_Mn, 242, P_Lo, 248, P_Po, 251, P_Lo, 252, P_Po, 253, P_Lo, 254, P_Cn, 0, P_Nd, 10, P_Lo, 38, P_Mn, 46, P_Po, 48, P_Lo, 71, P_Mn, 82, P_Mc, 84, P_Cn, 95, P_Po, 96, P_Lo, 125, P_Cn, 128, P_Mn, 131, P_Mc, 132, P_Lo, 179, P_Mn, 180, P_Mc, 182, P_Mn, 186, P_Mc, 188, P_Mn, 189, P_Mc, 193, P_Po, 206, P_Cn, 207, P_Lm, 208, P_Nd, 218, P_Cn, 222, P_Po, 224, P_Lo, 229, P_Mn, 230, P_Lm, 231, P_Lo, 240, P_Nd, 250, P_Lo, 255, P_Cn, 0, P_Lo, 41, P_Mn, 47, P_Mc, 49, P_Mn, 51, P_Mc, 53, P_Mn, 55, P_Cn, 64, P_Lo, 67, P_Mn, 68, P_Lo, 76, P_Mn, 77, P_Mc, 78, P_Cn, 80, P_Nd, 90, P_Cn, 92, P_Po, 96, P_Lo, 112, P_Lm, 113, P_Lo, 119, P_So, 122, P_Lo, 123, P_Mc, 124, P_Mn, 125, P_Mc, 126, P_Lo, 176, P_Mn, 177, P_Lo, 178, P_Mn, 181, P_Lo, 183, P_Mn, 185, P_Lo, 190, P_Mn, 192, P_Lo, 193, P_Mn, 194, P_Lo, 195, P_Cn, 219, P_Lo, 221, P_Lm, 222, P_Po, 224, P_Lo, 235, P_Mc, 236, P_Mn, 238, P_Mc, 240, P_Po, 242, P_Lo, 243, P_Lm, 245, P_Mc, 246, P_Mn, 247, P_Cn, 0, P_Cn, 1, P_Lo, 7, P_Cn, 9, P_Lo, 15, P_Cn, 17, P_Lo, 23, P_Cn, 32, P_Lo, 39, P_Cn, 40, P_Lo, 47, P_Cn, 48, P_Ll, 91, P_Sk, 92, P_Lm, 96, P_Ll, 102, P_Cn, 112, P_Ll, 192, P_Lo, 227, P_Mc, 229, P_Mn, 230, P_Mc, 232, P_Mn, 233, P_Mc, 235, P_Po, 236, P_Mc, 237, P_Mn, 238, P_Cn, 240, P_Nd, 250, P_Cn, 0, P_Cn, 163, P_Lo, 164, P_Cn, 176, P_Lo, 199, P_Cn, 203, P_Lo, 252, P_Cn, 0, P_Cs, 1, P_Cn, 0, P_Cn, 127, P_Cs, 129, P_Cn, 255, P_Cs, 0, P_Cn, 255, P_Cs, 0, P_Co, 1, P_Cn, 0, P_Cn, 255, P_Co, 0, P_Lo, 110, P_Cn, 112, P_Lo, 218, P_Cn, 0, P_Ll, 7, P_Cn, 19, P_Ll, 24, P_Cn, 29, P_Lo, 30, P_Mn, 31, P_Lo, 41, P_Sm, 42, P_Lo, 55, P_Cn, 56, P_Lo, 61, P_Cn, 62, P_Lo, 63, P_Cn, 64, P_Lo, 66, P_Cn, 67, P_Lo, 69, P_Cn, 70, P_Lo, 178, P_Sk, 194, P_Cn, 211, P_Lo, 0, P_Lo, 62, P_Pe, 63, P_Ps, 64, P_Cn, 80, P_Lo, 144, P_Cn, 146, P_Lo, 200, P_Cn, 240, P_Lo, 252, P_Sc, 253, P_So, 254, P_Cn, 0, P_Mn, 16, P_Po, 23, P_Ps, 24, P_Pe, 25, P_Po, 26, P_Cn, 32, P_Mn, 48, P_Po, 49, P_Pd, 51, P_Pc, 53, P_Ps, 54, P_Pe, 55, P_Ps, 56, P_Pe, 57, P_Ps, 58, P_Pe, 59, P_Ps, 60, P_Pe, 61, P_Ps, 62, P_Pe, 63, P_Ps, 64, P_Pe, 65, P_Ps, 66, P_Pe, 67, P_Ps, 68, P_Pe, 69, P_Po, 71, P_Ps, 72, P_Pe, 73, P_Po, 77, P_Pc, 80, P_Po, 83, P_Cn, 84, P_Po, 88, P_Pd, 89, P_Ps, 90, P_Pe, 91, P_Ps, 92, P_Pe, 93, P_Ps, 94, P_Pe, 95, P_Po, 98, P_Sm, 99, P_Pd, 100, P_Sm, 103, P_Cn, 104, P_Po, 105, P_Sc, 106, P_Po, 108, P_Cn, 112, P_Lo, 117, P_Cn, 118, P_Lo, 253, P_Cn, 255, P_Cf, 0, P_Cn, 1, P_Po, 4, P_Sc, 5, P_Po, 8, P_Ps, 9, P_Pe, 10, P_Po, 11, P_Sm, 12, P_Po, 13, P_Pd, 14, P_Po, 16, P_Nd, 26, P_Po, 28, P_Sm, 31, P_Po, 33, P_Lu, 59, P_Ps, 60, P_Po, 61, P_Pe, 62, P_Sk, 63, P_Pc, 64, P_Sk, 65, P_Ll, 91, P_Ps, 92, P_Sm, 93, P_Pe, 94, P_Sm, 95, P_Ps, 96, P_Pe, 97, P_Po, 98, P_Ps, 99, P_Pe, 100, P_Po, 102, P_Lo, 112, P_Lm, 113, P_Lo, 158, P_Lm, 160, P_Lo, 191, P_Cn, 194, P_Lo, 200, P_Cn, 202, P_Lo, 208, P_Cn, 210, P_Lo, 216, P_Cn, 218, P_Lo, 221, P_Cn, 224, P_Sc, 226, P_Sm, 227, P_Sk, 228, P_So, 229, P_Sc, 231, P_Cn, 232, P_So, 233, P_Sm, 237, P_So, 239, P_Cn, 249, P_Cf, 252, P_So, 254, P_Cn, 0, P_Lo, 12, P_Cn, 13, P_Lo, 39, P_Cn, 40, P_Lo, 59, P_Cn, 60, P_Lo, 62, P_Cn, 63, P_Lo, 78, P_Cn, 80, P_Lo, 94, P_Cn, 128, P_Lo, 251, P_Cn, 0, P_Po, 3, P_Cn, 7, P_No, 52, P_Cn, 55, P_So, 64, P_Nl, 117, P_No, 121, P_So, 138, P_No, 140, P_So, 143, P_Cn, 144, P_So, 156, P_Cn, 160, P_So, 161, P_Cn, 208, P_So, 253, P_Mn, 254, P_Cn, 0, P_Cn, 128, P_Lo, 157, P_Cn, 160, P_Lo, 209, P_Cn, 224, P_Mn, 225, P_No, 252, P_Cn, 0, P_Lo, 32, P_No, 36, P_Cn, 48, P_Lo, 65, P_Nl, 66, P_Lo, 74, P_Nl, 75, P_Cn, 80, P_Lo, 118, P_Mn, 123, P_Cn, 128, P_Lo, 158, P_Cn, 159, P_Po, 160, P_Lo, 196, P_Cn, 200, P_Lo, 208, P_Po, 209, P_Nl, 214, P_Cn, 0, P_Lu, 40, P_Ll, 80, P_Lo, 158, P_Cn, 160, P_Nd, 170, P_Cn, 176, P_Lu, 212, P_Cn, 216, P_Ll, 252, P_Cn, 0, P_Lo, 40, P_Cn, 48, P_Lo, 100, P_Cn, 111, P_Po, 112, P_Cn, 0, P_Lo, 55, P_Cn, 64, P_Lo, 86, P_Cn, 96, P_Lo, 104, P_Cn, 0, P_Lo, 6, P_Cn, 8, P_Lo, 9, P_Cn, 10, P_Lo, 54, P_Cn, 55, P_Lo, 57, P_Cn, 60, P_Lo, 61, P_Cn, 63, P_Lo, 86, P_Cn, 87, P_Po, 88, P_No, 96, P_Lo, 119, P_So, 121, P_No, 128, P_Lo, 159, P_Cn, 167, P_No, 176, P_Cn, 224, P_Lo, 243, P_Cn, 244, P_Lo, 246, P_Cn, 251, P_No, 0, P_Lo, 22, P_No, 28, P_Cn, 31, P_Po, 32, P_Lo, 58, P_Cn, 63, P_Po, 64, P_Cn, 128, P_Lo, 184, P_Cn, 188, P_No, 190, P_Lo, 192, P_No, 208, P_Cn, 210, P_No, 0, P_Lo, 1, P_Mn, 4, P_Cn, 5, P_Mn, 7, P_Cn, 12, P_Mn, 16, P_Lo, 20, P_Cn, 21, P_Lo, 24, P_Cn, 25, P_Lo, 52, P_Cn, 56, P_Mn, 59, P_Cn, 63, P_Mn, 64, P_No, 72, P_Cn, 80, P_Po, 89, P_Cn, 96, P_Lo, 125, P_No, 127, P_Po, 128, P_Lo, 157, P_No, 160, P_Cn, 192, P_Lo, 200, P_So, 201, P_Lo, 229, P_Mn, 231, P_Cn, 235, P_No, 240, P_Po, 247, P_Cn, 0, P_Lo, 54, P_Cn, 57, P_Po, 64, P_Lo, 86, P_Cn, 88, P_No, 96, P_Lo, 115, P_Cn, 120, P_No, 128, P_Lo, 146, P_Cn, 153, P_Po, 157, P_Cn, 169, P_No, 176, P_Cn, 0, P_Lo, 73, P_Cn, 128, P_Lu, 179, P_Cn, 192, P_Ll, 243, P_Cn, 250, P_No, 0, P_Cn, 96, P_No, 127, P_Cn, 0, P_Mc, 1, P_Mn, 2, P_Mc, 3, P_Lo, 56, P_Mn, 71, P_Po, 78, P_Cn, 82, P_No, 102, P_Nd, 112, P_Cn, 127, P_Mn, 130, P_Mc, 131, P_Lo, 176, P_Mc, 179, P_Mn, 183, P_Mc, 185, P_Mn, 187, P_Po, 189, P_Cf, 190, P_Po, 194, P_Cn, 208, P_Lo, 233, P_Cn, 240, P_Nd, 250, P_Cn, 0, P_Mn, 3, P_Lo, 39, P_Mn, 44, P_Mc, 45, P_Mn, 53, P_Cn, 54, P_Nd, 64, P_Po, 68, P_Cn, 80, P_Lo, 115, P_Mn, 116, P_Po, 118, P_Lo, 119, P_Cn, 128, P_Mn, 130, P_Mc, 131, P_Lo, 179, P_Mc, 182, P_Mn, 191, P_Mc, 193, P_Lo, 197, P_Po, 202, P_Mn, 205, P_Po, 206, P_Cn, 208, P_Nd, 218, P_Lo, 219, P_Po, 220, P_Lo, 221, P_Po, 224, P_Cn, 225, P_No, 245, P_Cn, 0, P_Lo, 18, P_Cn, 19, P_Lo, 44, P_Mc, 47, P_Mn, 50, P_Mc, 52, P_Mn, 53, P_Mc, 54, P_Mn, 56, P_Po, 62, P_Mn, 63, P_Cn, 128, P_Lo, 135, P_Cn, 136, P_Lo, 137, P_Cn, 138, P_Lo, 142, P_Cn, 143, P_Lo, 158, P_Cn, 159, P_Lo, 169, P_Po, 170, P_Cn, 176, P_Lo, 223, P_Mn, 224, P_Mc, 227, P_Mn, 235, P_Cn, 240, P_Nd, 250, P_Cn, 0, P_Mn, 2, P_Mc, 4, P_Cn, 5, P_Lo, 13, P_Cn, 15, P_Lo, 17, P_Cn, 19, P_Lo, 41, P_Cn, 42, P_Lo, 49, P_Cn, 50, P_Lo, 52, P_Cn, 53, P_Lo, 58, P_Cn, 60, P_Mn, 61, P_Lo, 62, P_Mc, 64, P_Mn, 65, P_Mc, 69, P_Cn, 71, P_Mc, 73, P_Cn, 75, P_Mc, 78, P_Cn, 80, P_Lo, 81, P_Cn, 87, P_Mc, 88, P_Cn, 93, P_Lo, 98, P_Mc, 100, P_Cn, 102, P_Mn, 109, P_Cn, 112, P_Mn, 117, P_Cn, 0, P_Lo, 53, P_Mc, 56, P_Mn, 64, P_Mc, 66, P_Mn, 69, P_Mc, 70, P_Mn, 71, P_Lo, 75, P_Po, 80, P_Nd, 90, P_Cn, 91, P_Po, 92, P_Cn, 93, P_Po, 94, P_Cn, 128, P_Lo, 176, P_Mc, 179, P_Mn, 185, P_Mc, 186, P_Mn, 187, P_Mc, 191, P_Mn, 193, P_Mc, 194, P_Mn, 196, P_Lo, 198, P_Po, 199, P_Lo, 200, P_Cn, 208, P_Nd, 218, P_Cn, 0, P_Cn, 128, P_Lo, 175, P_Mc, 178, P_Mn, 182, P_Cn, 184, P_Mc, 188, P_Mn, 190, P_Mc, 191, P_Mn, 193, P_Po, 216, P_Lo, 220, P_Mn, 222, P_Cn, 0, P_Lo, 48, P_Mc, 51, P_Mn, 59, P_Mc, 61, P_Mn, 62, P_Mc, 63, P_Mn, 65, P_Po, 68, P_Lo, 69, P_Cn, 80, P_Nd, 90, P_Cn, 96, P_Po, 109, P_Cn, 128, P_Lo, 171, P_Mn, 172, P_Mc, 173, P_Mn, 174, P_Mc, 176, P_Mn, 182, P_Mc, 183, P_Mn, 184, P_Cn, 192, P_Nd, 202, P_Cn, 0, P_Lo, 26, P_Cn, 29, P_Mn, 32, P_Mc, 34, P_Mn, 38, P_Mc, 39, P_Mn, 44, P_Cn, 48, P_Nd, 58, P_No, 60, P_Po, 63, P_So, 64, P_Cn, 0, P_Cn, 160, P_Lu, 192, P_Ll, 224, P_Nd, 234, P_No, 243, P_Cn, 255, P_Lo, 0, P_Cn, 192, P_Lo, 249, P_Cn, 0, P_Lo, 9, P_Cn, 10, P_Lo, 47, P_Mc, 48, P_Mn, 55, P_Cn, 56, P_Mn, 62, P_Mc, 63, P_Mn, 64, P_Lo, 65, P_Po, 70, P_Cn, 80, P_Nd, 90, P_No, 109, P_Cn, 112, P_Po, 114, P_Lo, 144, P_Cn, 146, P_Mn, 168, P_Cn, 169, P_Mc, 170, P_Mn, 177, P_Mc, 178, P_Mn, 180, P_Mc, 181, P_Mn, 183, P_Cn, 0, P_Lo, 154, P_Cn, 0, P_Nl, 111, P_Cn, 112, P_Po, 117, P_Cn, 128, P_Lo, 0, P_Lo, 68, P_Cn, 0, P_Lo, 47, P_Cn, 0, P_Lo, 71, P_Cn, 0, P_Lo, 57, P_Cn, 64, P_Lo, 95, P_Cn, 96, P_Nd, 106, P_Cn, 110, P_Po, 112, P_Cn, 208, P_Lo, 238, P_Cn, 240, P_Mn, 245, P_Po, 246, P_Cn, 0, P_Lo, 48, P_Mn, 55, P_Po, 60, P_So, 64, P_Lm, 68, P_Po, 69, P_So, 70, P_Cn, 80, P_Nd, 90, P_Cn, 91, P_No, 98, P_Cn, 99, P_Lo, 120, P_Cn, 125, P_Lo, 144, P_Cn, 0, P_Lo, 69, P_Cn, 80, P_Lo, 81, P_Mc, 127, P_Cn, 143, P_Mn, 147, P_Lm, 160, P_Cn, 224, P_Lm, 225, P_Cn, 0, P_Cn, 236, P_Lo, 237, P_Cn, 0, P_Lo, 243, P_Cn, 0, P_Lo, 2, P_Cn, 0, P_Lo, 107, P_Cn, 112, P_Lo, 125, P_Cn, 128, P_Lo, 137, P_Cn, 144, P_Lo, 154, P_Cn, 156, P_So, 157, P_Mn, 159, P_Po, 160, P_Cf, 164, P_Cn, 0, P_So, 246, P_Cn, 0, P_So, 39, P_Cn, 41, P_So, 101, P_Mc, 103, P_Mn, 106, P_So, 109, P_Mc, 115, P_Cf, 123, P_Mn, 131, P_So, 133, P_Mn, 140, P_So, 170, P_Mn, 174, P_So, 233, P_Cn, 0, P_So, 66, P_Mn, 69, P_So, 70, P_Cn, 0, P_So, 87, P_Cn, 96, P_No, 114, P_Cn, 0, P_Lu, 26, P_Ll, 52, P_Lu, 78, P_Ll, 85, P_Cn, 86, P_Ll, 104, P_Lu, 130, P_Ll, 156, P_Lu, 157, P_Cn, 158, P_Lu, 160, P_Cn, 162, P_Lu, 163, P_Cn, 165, P_Lu, 167, P_Cn, 169, P_Lu, 173, P_Cn, 174, P_Lu, 182, P_Ll, 186, P_Cn, 187, P_Ll, 188, P_Cn, 189, P_Ll, 196, P_Cn, 197, P_Ll, 208, P_Lu, 234, P_Ll, 0, P_Ll, 4, P_Lu, 6, P_Cn, 7, P_Lu, 11, P_Cn, 13, P_Lu, 21, P_Cn, 22, P_Lu, 29, P_Cn, 30, P_Ll, 56, P_Lu, 58, P_Cn, 59, P_Lu, 63, P_Cn, 64, P_Lu, 69, P_Cn, 70, P_Lu, 71, P_Cn, 74, P_Lu, 81, P_Cn, 82, P_Ll, 108, P_Lu, 134, P_Ll, 160, P_Lu, 186, P_Ll, 212, P_Lu, 238, P_Ll, 0, P_Ll, 8, P_Lu, 34, P_Ll, 60, P_Lu, 86, P_Ll, 112, P_Lu, 138, P_Ll, 166, P_Cn, 168, P_Lu, 193, P_Sm, 194, P_Ll, 219, P_Sm, 220, P_Ll, 226, P_Lu, 251, P_Sm, 252, P_Ll, 0, P_Ll, 21, P_Sm, 22, P_Ll, 28, P_Lu, 53, P_Sm, 54, P_Ll, 79, P_Sm, 80, P_Ll, 86, P_Lu, 111, P_Sm, 112, P_Ll, 137, P_Sm, 138, P_Ll, 144, P_Lu, 169, P_Sm, 170, P_Ll, 195, P_Sm, 196, P_Ll, 202, P_Lul, 204, P_Cn, 206, P_Nd, 0, P_Mn, 55, P_So, 59, P_Mn, 109, P_So, 117, P_Mn, 118, P_So, 132, P_Mn, 133, P_So, 135, P_Po, 140, P_Cn, 155, P_Mn, 160, P_Cn, 161, P_Mn, 176, P_Cn, 0, P_Mn, 7, P_Cn, 8, P_Mn, 25, P_Cn, 27, P_Mn, 34, P_Cn, 35, P_Mn, 37, P_Cn, 38, P_Mn, 43, P_Cn, 0, P_Lo, 197, P_Cn, 199, P_No, 208, P_Mn, 215, P_Cn, 0, P_Lu, 34, P_Ll, 68, P_Mn, 75, P_Cn, 80, P_Nd, 90, P_Cn, 94, P_Po, 96, P_Cn, 0, P_Lo, 4, P_Cn, 5, P_Lo, 32, P_Cn, 33, P_Lo, 35, P_Cn, 36, P_Lo, 37, P_Cn, 39, P_Lo, 40, P_Cn, 41, P_Lo, 51, P_Cn, 52, P_Lo, 56, P_Cn, 57, P_Lo, 58, P_Cn, 59, P_Lo, 60, P_Cn, 66, P_Lo, 67, P_Cn, 71, P_Lo, 72, P_Cn, 73, P_Lo, 74, P_Cn, 75, P_Lo, 76, P_Cn, 77, P_Lo, 80, P_Cn, 81, P_Lo, 83, P_Cn, 84, P_Lo, 85, P_Cn, 87, P_Lo, 88, P_Cn, 89, P_Lo, 90, P_Cn, 91, P_Lo, 92, P_Cn, 93, P_Lo, 94, P_Cn, 95, P_Lo, 96, P_Cn, 97, P_Lo, 99, P_Cn, 100, P_Lo, 101, P_Cn, 103, P_Lo, 107, P_Cn, 108, P_Lo, 115, P_Cn, 116, P_Lo, 120, P_Cn, 121, P_Lo, 125, P_Cn, 126, P_Lo, 127, P_Cn, 128, P_Lo, 138, P_Cn, 139, P_Lo, 156, P_Cn, 161, P_Lo, 164, P_Cn, 165, P_Lo, 170, P_Cn, 171, P_Lo, 188, P_Cn, 240, P_Sm, 242, P_Cn, 0, P_So, 44, P_Cn, 48, P_So, 148, P_Cn, 160, P_So, 175, P_Cn, 177, P_So, 192, P_Cn, 193, P_So, 208, P_Cn, 209, P_So, 246, P_Cn, 0, P_No, 13, P_Cn, 16, P_So, 47, P_Cn, 48, P_So, 108, P_Cn, 112, P_So, 173, P_Cn, 230, P_So, 0, P_So, 3, P_Cn, 16, P_So, 60, P_Cn, 64, P_So, 73, P_Cn, 80, P_So, 82, P_Cn, 0, P_So, 251, P_Sk, 0, P_So, 211, P_Cn, 224, P_So, 237, P_Cn, 240, P_So, 247, P_Cn, 0, P_So, 116, P_Cn, 128, P_So, 213, P_Cn, 0, P_So, 12, P_Cn, 16, P_So, 72, P_Cn, 80, P_So, 90, P_Cn, 96, P_So, 136, P_Cn, 144, P_So, 174, P_Cn, 0, P_Cn, 16, P_So, 31, P_Cn, 32, P_So, 40, P_Cn, 48, P_So, 49, P_Cn, 51, P_So, 63, P_Cn, 64, P_So, 76, P_Cn, 80, P_So, 95, P_Cn, 128, P_So, 146, P_Cn, 192, P_So, 193, P_Cn, 0, P_Cn, 214, P_Lo, 215, P_Cn, 0, P_Cn, 52, P_Lo, 53, P_Cn, 64, P_Lo, 65, P_Cn, 0, P_Cn, 29, P_Lo, 30, P_Cn, 32, P_Lo, 33, P_Cn, 0, P_Cn, 161, P_Lo, 162, P_Cn, 0, P_Lo, 30, P_Cn, 0, P_Cn, 1, P_Cf, 2, P_Cn, 32, P_Cf, 128, P_Cn, 0, P_Mn, 240, P_Cn, 0, P_Cn, 253, P_Co, 254, P_Cn, }; const unsigned int UnicodeProperty::property_offsets[] = { 0x0, 2, 122, 0x100, 122, 248, 0x200, 248, 294, 0x300, 294, 366, 0x400, 366, 390, 0x500, 390, 450, 0x600, 450, 520, 0x700, 520, 560, 0x800, 560, 606, 0x900, 606, 728, 0xA00, 728, 878, 0xB00, 878, 1040, 0xC00, 1040, 1174, 0xD00, 1174, 1290, 0xE00, 1290, 1398, 0xF00, 1398, 1486, 0x1000, 1486, 1576, 0x1100, 1576, 1578, 0x1200, 1578, 1632, 0x1300, 1632, 1666, 0x1400, 1666, 1670, 0x1500, 1576, 1578, 0x1600, 1670, 1696, 0x1700, 1696, 1770, 0x1800, 1770, 1810, 0x1900, 1810, 1866, 0x1A00, 1866, 1930, 0x1B00, 1930, 2012, 0x1C00, 2012, 2076, 0x1D00, 2076, 2094, 0x1E00, 2094, 2100, 0x1F00, 2100, 2228, 0x2000, 2228, 2342, 0x2100, 2342, 2474, 0x2200, 2474, 2476, 0x2300, 2476, 2512, 0x2400, 2512, 2526, 0x2500, 2526, 2538, 0x2600, 2538, 2544, 0x2700, 2544, 2608, 0x2800, 2608, 2610, 0x2900, 2610, 2674, 0x2A00, 2474, 2476, 0x2B00, 2674, 2706, 0x2C00, 2706, 2760, 0x2D00, 2760, 2822, 0x2E00, 2822, 2908, 0x2F00, 2908, 2916, 0x3000, 2916, 3020, 0x3100, 3020, 3046, 0x3200, 3046, 3072, 0x3300, 2608, 2610, 0x3400, 3072, 3076, 0x3500, 0, 2, 0x4D00, 3076, 3084, 0x4E00, 3072, 3076, 0x4F00, 0, 2, 0x9F00, 3084, 3090, 0xA000, 3090, 3096, 0xA100, 1576, 1578, 0xA400, 3096, 3110, 0xA500, 1576, 1578, 0xA600, 3110, 3156, 0xA700, 3156, 3214, 0xA800, 3214, 3284, 0xA900, 3284, 3350, 0xAA00, 3350, 3448, 0xAB00, 3448, 3506, 0xAC00, 3072, 3076, 0xAD00, 0, 2, 0xD700, 3506, 3520, 0xD800, 3520, 3524, 0xD900, 0, 2, 0xDB00, 3524, 3532, 0xDC00, 3520, 3524, 0xDD00, 0, 2, 0xDF00, 3532, 3536, 0xE000, 3536, 3540, 0xE100, 0, 2, 0xF800, 3540, 3544, 0xF900, 1576, 1578, 0xFA00, 3544, 3552, 0xFB00, 3552, 3596, 0xFC00, 1576, 1578, 0xFD00, 3596, 3620, 0xFE00, 3620, 3730, 0xFF00, 3730, 3850, 0x10000, 3850, 3878, 0x10100, 3878, 3914, 0x10200, 3914, 3930, 0x10300, 3930, 3970, 0x10400, 3970, 3990, 0x10500, 3990, 4002, 0x10600, 1576, 1578, 0x10700, 4002, 4014, 0x10800, 4014, 4066, 0x10900, 4066, 4096, 0x10A00, 4096, 4162, 0x10B00, 4162, 4192, 0x10C00, 4192, 4206, 0x10D00, 0, 2, 0x10E00, 4206, 4212, 0x10F00, 0, 2, 0x11000, 4212, 4262, 0x11100, 4262, 4328, 0x11200, 4328, 4388, 0x11300, 4388, 4460, 0x11400, 4460, 4520, 0x11500, 4520, 4546, 0x11600, 4546, 4596, 0x11700, 4596, 4622, 0x11800, 4622, 4636, 0x11900, 0, 2, 0x11A00, 4636, 4642, 0x11B00, 0, 2, 0x11C00, 4642, 4696, 0x11D00, 0, 2, 0x12000, 1576, 1578, 0x12300, 4696, 4700, 0x12400, 4700, 4710, 0x12500, 4710, 4714, 0x12600, 0, 2, 0x13000, 1576, 1578, 0x13400, 4714, 4718, 0x13500, 0, 2, 0x14400, 1576, 1578, 0x14600, 4718, 4722, 0x14700, 0, 2, 0x16800, 1576, 1578, 0x16A00, 4722, 4748, 0x16B00, 4748, 4780, 0x16C00, 0, 2, 0x16F00, 4780, 4800, 0x17000, 3072, 3076, 0x17100, 0, 2, 0x18700, 4800, 4806, 0x18800, 1576, 1578, 0x18A00, 4806, 4810, 0x18B00, 0, 2, 0x1B000, 4810, 4814, 0x1B100, 0, 2, 0x1BC00, 4814, 4840, 0x1BD00, 0, 2, 0x1D000, 4840, 4844, 0x1D100, 4844, 4874, 0x1D200, 4874, 4882, 0x1D300, 4882, 4890, 0x1D400, 4890, 4946, 0x1D500, 4946, 5000, 0x1D600, 5000, 5032, 0x1D700, 5032, 5074, 0x1D800, 2608, 2610, 0x1DA00, 5074, 5102, 0x1DB00, 0, 2, 0x1E000, 5102, 5122, 0x1E100, 0, 2, 0x1E800, 5122, 5132, 0x1E900, 5132, 5148, 0x1EA00, 0, 2, 0x1EE00, 5148, 5284, 0x1EF00, 0, 2, 0x1F000, 5284, 5308, 0x1F100, 5308, 5326, 0x1F200, 5326, 5342, 0x1F300, 5342, 5346, 0x1F400, 2608, 2610, 0x1F600, 5346, 5358, 0x1F700, 5358, 5366, 0x1F800, 5366, 5386, 0x1F900, 5386, 5420, 0x1FA00, 0, 2, 0x20000, 3072, 3076, 0x20100, 0, 2, 0x2A600, 5420, 5426, 0x2A700, 3072, 3076, 0x2A800, 0, 2, 0x2B700, 5426, 5436, 0x2B800, 5436, 5446, 0x2B900, 0, 2, 0x2CE00, 5446, 5452, 0x2CF00, 0, 2, 0x2F800, 1576, 1578, 0x2FA00, 5452, 5456, 0x2FB00, 0, 2, 0xE0000, 5456, 5466, 0xE0100, 5466, 5470, 0xE0200, 0, 2, 0xF0000, 3536, 3540, 0xF0100, 0, 2, 0xFFF00, 5470, 5476, 0x100000, 3536, 3540, 0x100100, 0, 2, 0x10FF00, 5470, 5476, 0x110000, 0, 2, }; const int UnicodeProperty::nproperty_offsets = (sizeof(UnicodeProperty::property_offsets) / (3*sizeof(unsigned int))); inline const unsigned int * UnicodeProperty::find_offset(uint32_t u) { // Up to U+1A00 each page has its own definition. if (u < 0x1A00) return &property_offsets[3*(u >> 8)]; // At or after U+1A00, binary search. int l = 0x1A, r = nproperty_offsets - 2; while (l <= r) { int m = (l + r) / 2; const unsigned int *ptr = &property_offsets[3*m]; if (u < ptr[0]) r = m - 1; else if (u >= ptr[3]) l = m + 1; else return ptr; } // If search fails, return last record, which will be all-unassigned. return &property_offsets[3*(nproperty_offsets - 1)]; } int UnicodeProperty::property(uint32_t u) { const unsigned int *offsets = find_offset(u); // Now we only care about the last byte. u &= 255; // Binary search within record. int l = offsets[1], r = offsets[2] - 4; const unsigned char *the_ptr; while (l <= r) { int m = ((l + r) / 2) & ~1; const unsigned char *ptr = &property_pages[m]; if (u < ptr[0]) r = m - 2; else if (u >= ptr[2]) l = m + 2; else { the_ptr = ptr; goto found_ptr; } } the_ptr = &property_pages[l]; found_ptr: // Found right block. if (the_ptr[1] == P_Lul) return ((u - the_ptr[0]) % 2 ? P_Ll : P_Lu); else return the_ptr[1]; } static const char property_names[] = "Cn\0Co\0Cs\0Cf\0Cc\0\0\0\0\0\0\0\0\0\0" "Zs\0Zl\0Zp\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "Mn\0Mc\0Me\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "Lo\0Lu\0Ll\0Lt\0Lm\0\0\0\0\0\0\0\0\0\0" "No\0Nd\0Nl\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "Po\0Pc\0Pd\0Ps\0Pe\0Pi\0Pf\0\0\0\0" "So\0Sm\0Sc\0Sk"; static const char * const property_long_names[] = { "Unassigned", "PrivateUse", "Surrogate", "Format", "Control", 0, 0, 0, "SpaceSeparator", "LineSeparator", "ParagraphSeparator", 0, 0, 0, 0, 0, "NonspacingMark", "SpacingMark", "EnclosingMark", 0, 0, 0, 0, 0, "OtherLetter", "UppercaseLetter", "LowercaseLetter", "TitlecaseLetter", "ModifierLetter", 0, 0, 0, "OtherNumber", "DecimalNumber", "LetterNumber", 0, 0, 0, 0, 0, "OtherPunctuation", "ConnectorPunctuation", "DashPunctuation", "OpenPunctuation", "ClosePunctuation", "InitialPunctuation", "FinalPunctuation", 0, "OtherSymbol", "MathSymbol", "CurrencySymbol", "ModifierSymbol" }; static const char * const property_category_long_names[] = { "Other", "Separator", "Mark", "Letter", "Number", "Punctuation", "Symbol" }; const char * UnicodeProperty::property_name(int p) { if (p >= 0 && p <= P_Sk && property_names[p*3]) return &property_names[p*3]; else return "?"; } bool UnicodeProperty::parse_property(const String &s, int &prop, int &prop_mask) { if (s.length() == 0) return false; else if (s.length() <= 2) { for (int i = 0; i <= P_S; i += 010) if (property_names[3*i] == s[0]) { if (s.length() == 1) { prop = i; prop_mask = P_TMASK; return true; } for (; property_names[3*i]; i++) if (property_names[3*i+1] == s[1]) { prop = i; prop_mask = 0377; return true; } break; } return false; } else { const char * const *dict = property_category_long_names; for (int i = 0; i <= P_S; i += 010, dict++) if (s == *dict) { prop = i; prop_mask = P_TMASK; return true; } dict = property_long_names; for (int i = 0; i <= P_Sk; i++, dict++) if (*dict && s == *dict) { prop = i; prop_mask = 0377; return true; } return false; } } lcdf-typetools-2.108/otftotfm/dvipsencoding.cc0000644000175000017500000010375113423375330016434 00000000000000/* dvipsencoding.{cc,hh} -- store a DVIPS encoding * * Copyright (c) 2003-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include "dvipsencoding.hh" #include "metrics.hh" #include "secondary.hh" #include #include #include #include #include #include #include #include "util.hh" enum { GLYPHLIST_ALTERNATIVE = 0x40000000, GLYPHLIST_USEMAP = GLYPHLIST_ALTERNATIVE, U_EMPTYSLOT = 0xD801, U_ALTSELECTOR = 0xD802 }; static HashMap glyphlist((uint32_t) -1); static Vector glyphmap; static PermString::Initializer perm_initializer; PermString DvipsEncoding::dot_notdef(".notdef"); #define NEXT_GLYPH_NAME(gn) ("/" + (gn)) void DvipsEncoding::add_glyphlist(String text) { const char *s = text.begin(), *end = text.end(); while (s != end) { // move to first nonblank while (s != end && isspace((unsigned char) *s)) ++s; // ignore comments if (s != end && *s == '#') { skip_to_end_of_line: while (s != end && *s != '\n' && *s != '\r') ++s; continue; } // parse glyph name const char *name_start = s; while (s != end && !isspace((unsigned char) *s) && *s != ';') ++s; if (s == name_start) goto skip_to_end_of_line; String glyph_name = text.substring(name_start, s).compact(); int map_pos = glyphmap.size(); // parse Unicodes while (1) { while (s != end && (*s == ' ' || *s == '\t')) ++s; if (s == end || *s == '\n' || *s == '\r' || *s == '#' || (map_pos == glyphmap.size() && *s != ';' && *s != ',')) break; if (*s == ';' || *s == ',') { ++s; while (s != end && (*s == ' ' || *s == '\t')) ++s; if (s == end || !isxdigit((unsigned char) *s)) goto skip_to_end_of_line; if (map_pos != glyphmap.size()) glyphmap.push_back(GLYPHLIST_ALTERNATIVE); } uint32_t u = 0; while (s != end && isxdigit((unsigned char) *s)) { if (*s >= '0' && *s <= '9') u = (u << 4) + *s - '0'; else if (*s >= 'A' && *s <= 'F') u = (u << 4) + *s - 'A' + 10; else u = (u << 4) + *s - 'a' + 10; ++s; } if (u == 0 || u > 0x10FFFF) goto skip_to_end_of_line; glyphmap.push_back(u); if (s != end && !isspace((unsigned char) *s) && *s != ',' && *s != ';') break; } // store result if (map_pos == glyphmap.size() - 1) { glyphlist.insert(glyph_name, glyphmap.back()); glyphmap.pop_back(); } else { glyphlist.insert(glyph_name, map_pos | GLYPHLIST_USEMAP); glyphmap.push_back(0); } goto skip_to_end_of_line; } } static void unicode_add_suffix(Vector &prefix, int prefix_starting_from, const Vector &suffix) { int prefix_size = prefix.size(); for (Vector::const_iterator it = suffix.begin(); it != suffix.end() && *it != 0; ++it) if (*it == GLYPHLIST_ALTERNATIVE) { prefix.push_back(*it); for (int i = prefix_starting_from; i < prefix_size; ++i) prefix.push_back(prefix[i]); } else prefix.push_back(*it); } bool DvipsEncoding::glyphname_unicode(String gn, Vector &unis) { int unis_first_size = unis.size(); // drop all characters to the right of the first dot String::iterator dot = std::find(gn.begin(), gn.end(), '.'); if (dot > gn.begin() && dot < gn.end()) gn = gn.substring(gn.begin(), dot); // map the first component, handle later components recursively String::iterator underscore = std::find(gn.begin(), gn.end(), '_'); String component = gn.substring(gn.begin(), underscore); int prefix_start = 0; Vector suffix; if (String gn_suffix = gn.substring(underscore + 1, gn.end())) { if (!glyphname_unicode(gn_suffix, suffix)) return false; } // check glyphlist int value = glyphlist[component]; uint32_t uval; if (value >= 0 && !(value & GLYPHLIST_USEMAP)) unis.push_back(value); else if (value >= 0) { for (int i = (value & ~GLYPHLIST_USEMAP); glyphmap[i]; ++i) if (glyphmap[i] == GLYPHLIST_ALTERNATIVE) { unicode_add_suffix(unis, prefix_start, suffix); unis.push_back(GLYPHLIST_ALTERNATIVE); prefix_start = unis.size(); } else unis.push_back(glyphmap[i]); } else if (component.length() >= 7 && (component.length() % 4) == 3 && (memcmp(component.data(), "uni", 3) == 0 // 16.Aug.2008: Some texnansx.enc have incorrect "Uni" // prefix, but we might as well understand it. || memcmp(component.data(), "Uni", 3) == 0)) { for (const char *s = component.begin() + 3; s < component.end(); s += 4) if (parse_unicode_number(s, s + 4, -1, uval)) unis.push_back(uval); else { unis.resize(unis_first_size); return false; } } else if (component.length() >= 5 && component.length() <= 7 && component[0] == 'u' && parse_unicode_number(component.begin() + 1, component.end(), -1, uval)) unis.push_back(uval); else return false; unicode_add_suffix(unis, prefix_start, suffix); return true; } DvipsEncoding::DvipsEncoding() : _boundary_char(-1), _altselector_char(-1), _unicoding_map(-1), _warn_missing(false) { } void DvipsEncoding::encode(int e, PermString what) { if (e >= _e.size()) _e.resize(e + 1, dot_notdef); _e[e] = what; } int DvipsEncoding::encoding_of(PermString what, bool encoding_required) { int slot = -1; for (int i = 0; i < _e.size(); i++) if (_e[i] == what) { slot = i; goto use_slot; } else if (!_e[i] || _e[i] == dot_notdef) slot = i; if (what == "||") return _boundary_char; else if (!encoding_required || slot < 0) return -1; use_slot: if (encoding_required) { if (slot >= _encoding_required.size()) _encoding_required.resize(slot + 1, false); _encoding_required[slot] = true; this->encode(slot, what); } return slot; } static String tokenize(const String &s, int &pos_in, int &line) { const char *data = s.data(); int len = s.length(); int pos = pos_in; while (1) { // skip whitespace while (pos < len && isspace((unsigned char) data[pos])) { if (data[pos] == '\n') line++; else if (data[pos] == '\r' && (pos + 1 == len || data[pos+1] != '\n')) line++; pos++; } if (pos >= len) { pos_in = len; return String(); } else if (data[pos] == '%') { for (pos++; pos < len && data[pos] != '\n' && data[pos] != '\r'; pos++) /* nada */; } else if (data[pos] == '[' || data[pos] == ']' || data[pos] == '{' || data[pos] == '}') { pos_in = pos + 1; return s.substring(pos, 1); } else if (data[pos] == '(') { int first = pos, nest = 0; for (pos++; pos < len && (data[pos] != ')' || nest); pos++) switch (data[pos]) { case '(': nest++; break; case ')': nest--; break; case '\\': if (pos + 1 < len) pos++; break; case '\n': line++; break; case '\r': if (pos + 1 == len || data[pos+1] != '\n') line++; break; } pos_in = (pos < len ? pos + 1 : len); return s.substring(first, pos_in - first); } else { int first = pos; while (pos < len && data[pos] == '/') pos++; while (pos < len && data[pos] != '/' && !isspace((unsigned char) data[pos]) && data[pos] != '[' && data[pos] != ']' && data[pos] != '%' && data[pos] != '(' && data[pos] != '{' && data[pos] != '}') pos++; pos_in = pos; return s.substring(first, pos - first); } } } static String comment_tokenize(const String &s, int &pos_in, int &line) { const char *data = s.data(); int len = s.length(); int pos = pos_in; while (1) { while (pos < len && data[pos] != '%' && data[pos] != '(') { if (data[pos] == '\n') line++; else if (data[pos] == '\r' && (pos + 1 == len || data[pos+1] != '\n')) line++; pos++; } if (pos >= len) { pos_in = len; return String(); } else if (data[pos] == '%') { for (pos++; pos < len && (data[pos] == ' ' || data[pos] == '\t'); pos++) /* nada */; int first = pos; for (; pos < len && data[pos] != '\n' && data[pos] != '\r'; pos++) /* nada */; pos_in = pos; if (pos > first) return s.substring(first, pos - first); } else { int nest = 0; for (pos++; pos < len && (data[pos] != ')' || nest); pos++) switch (data[pos]) { case '(': nest++; break; case ')': nest--; break; case '\\': if (pos + 1 < len) pos++; break; case '\n': line++; break; case '\r': if (pos + 1 == len || data[pos+1] != '\n') line++; break; } } } } static bool retokenize_isword(char c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '.' || c == '_'; } static struct { const char *s; int v; } ligkern_ops[] = { { "=:", DvipsEncoding::JL_LIG }, { "|=:", DvipsEncoding::JL_CLIG }, { "|=:>", DvipsEncoding::JL_CLIG_S }, { "=:|", DvipsEncoding::JL_LIGC }, { "=:|>", DvipsEncoding::JL_LIGC_S }, { "|=:|", DvipsEncoding::JL_CLIGC }, { "|=:>", DvipsEncoding::JL_CLIGC_S }, { "|=:|>>", DvipsEncoding::JL_CLIGC_SS }, { "{}", DvipsEncoding::JT_KERN }, { "{K}", DvipsEncoding::JT_KERN }, { "{L}", DvipsEncoding::JT_LIG }, { "{LK}", DvipsEncoding::JT_NOLIGKERN }, { "{KL}", DvipsEncoding::JT_NOLIGKERN }, { "{k}", DvipsEncoding::JT_KERN }, { "{l}", DvipsEncoding::JT_LIG }, { "{lk}", DvipsEncoding::JT_NOLIGKERN }, { "{kl}", DvipsEncoding::JT_NOLIGKERN }, // some encodings have @{@} instead of {} { "@{@}", DvipsEncoding::JT_KERN }, { 0, 0 } }; static int find_ligkern_op(const String &s) { for (int i = 0; ligkern_ops[i].s; i++) if (ligkern_ops[i].s == s) return ligkern_ops[i].v; return 0; } inline bool operator==(const DvipsEncoding::Ligature& l1, const DvipsEncoding::Ligature& l2) { return l1.c1 == l2.c1 && l1.c2 == l2.c2; } void DvipsEncoding::add_ligkern(const Ligature &l, int override) { Ligature *old = std::find(_lig.begin(), _lig.end(), l); if (old == _lig.end()) _lig.push_back(l); else { if ((l.join & JT_KERN) && (override > 0 || !(old->join & JT_KERN))) { old->join |= JT_KERN; old->k = l.k; } if ((l.join & JT_LIG) && (override > 0 || !(old->join & JT_LIG))) { old->join = (old->join & JT_KERN) | (l.join & JT_LIGALL); old->d = l.d; } } } int DvipsEncoding::parse_ligkern_words(Vector &v, int override, ErrorHandler *errh) { _file_had_ligkern = true; int op; long l; char *endptr; if (v.size() == 3) { // empty string fails if (!v[0]) return -1; // boundary char setting if (v[0] == "||" && v[1] == "=") { char *endptr; if (override > 0 || _boundary_char < 0) _boundary_char = strtol(v[2].c_str(), &endptr, 10); if (*endptr == 0 && _boundary_char < _e.size()) return 0; else return errh->error("parse error in boundary character assignment"); } // altselector char setting if (v[0] == "^^" && v[1] == "=") { char *endptr; if (override > 0 || _altselector_char < 0) _altselector_char = strtol(v[2].c_str(), &endptr, 10); if (*endptr == 0 && _altselector_char < _e.size()) return 0; else return errh->error("parse error in altselector character assignment"); } // encoding l = strtol(v[0].c_str(), &endptr, 0); if (endptr == v[0].end() && v[1] == "=") { if (l >= 0 && l < 256) { if (override > 0 || !_e[l]) encode(l, v[2]); return 0; } else return errh->error("encoding value %<%d%> out of range", l); } // kern operation if (v[1].length() >= 3 && v[1][0] == '{' && v[1].back() == '}') { String middle = v[1].substring(1, v[1].length() - 2); l = strtol(middle.c_str(), &endptr, 0); if (endptr == middle.end()) { op = JT_KERN; goto found_kernop; } } op = find_ligkern_op(v[1]); if (!op || (op & JT_ADDLIG)) return -1; found_kernop: int av = (v[0] == "*" ? J_ALL : encoding_of(v[0])); if (av < 0) return errh->warning("bad %<%s%> (%<%s%> has no encoding)", v[1].c_str(), v[0].c_str()); int bv = (v[2] == "*" ? J_ALL : encoding_of(v[2])); if (bv < 0) return errh->warning("bad %<%s%> (%<%s%> has no encoding)", v[1].c_str(), v[2].c_str()); if ((op & JT_KERN) && l && (av == J_ALL || bv == J_ALL)) return errh->warning("%<%s %s %s%> illegal, only {0} works with *", v[0].c_str(), v[1].c_str(), v[2].c_str()); Ligature lig = { av, bv, op, static_cast(l), 0 }; add_ligkern(lig, override); return 0; } else if (v.size() == 4 && ((op = find_ligkern_op(v[2])) & JT_ADDLIG)) { int av = encoding_of(v[0], override > 0); if (av < 0) return (override > 0 ? errh->warning("bad ligature (%<%s%> has no encoding)", v[0].c_str()) : -1); int bv = encoding_of(v[1], override > 0); if (bv < 0) return (override > 0 ? errh->warning("bad ligature (%<%s%> has no encoding)", v[1].c_str()) : -1); int cv = encoding_of(v[3], override > 0); if (cv < 0) return (override > 0 ? errh->warning("bad ligature (%<%s%> has no encoding)", v[3].c_str()) : -1); Ligature lig = { av, bv, op, 0, cv }; add_ligkern(lig, override); return 0; } else return -EPARSE; } int DvipsEncoding::parse_position_words(Vector &v, int override, ErrorHandler *errh) { if (v.size() != 4) return -EPARSE; int c = encoding_of(v[0]); if (c < 0) return (override > 0 ? errh->warning("bad positioning (%<%s%> has no encoding)", v[0].c_str()) : -1); char *endptr; int pdx, pdy, adx; if (!v[1] || !v[2] || !v[3] || (pdx = strtol(v[1].c_str(), &endptr, 10), *endptr) || (pdy = strtol(v[2].c_str(), &endptr, 10), *endptr) || (adx = strtol(v[3].c_str(), &endptr, 10), *endptr)) return errh->error("parse error in POSITION"); Ligature l = { c, pdx, pdy, adx, 0 }; Ligature *old = std::find(_pos.begin(), _pos.end(), l); if (old == _pos.end()) _pos.push_back(l); else if (override > 0) *old = l; return 0; } int DvipsEncoding::parse_unicoding_words(Vector &v, int override, ErrorHandler *errh) { int av; if (v.size() < 2 || (v[1] != "=" && v[1] != "=:" && v[1] != ":=")) return -EPARSE; else if (v[0] == "||" || (av = encoding_of(v[0])) < 0) return errh->warning("bad UNICODING (%<%s%> has no encoding)", v[0].c_str()); int original_size = _unicoding.size(); if (v.size() == 2 || (v.size() == 3 && v[2] == dot_notdef)) /* no warnings to delete a glyph */; else { for (int i = 2; i < v.size(); i++) { if (_unicoding.size() != original_size) _unicoding.push_back(GLYPHLIST_ALTERNATIVE); if (!glyphname_unicode(v[i], _unicoding)) { errh->warning("can%,t map %<%s%> to Unicode", v[i].c_str()); if (i == v.size() - 1 && _unicoding.size() == original_size) errh->warning("target %<%s%> will be deleted from encoding", v[0].c_str()); else if (_unicoding.size() != original_size) _unicoding.pop_back(); } } } _unicoding.push_back(0); if (override > 0 || _unicoding_map[v[0]] < 0) _unicoding_map.insert(v[0], original_size); return 0; } const DvipsEncoding::WordType DvipsEncoding::word_types[] = { { "LIGKERN", &DvipsEncoding::parse_ligkern_words }, { "POSITION", &DvipsEncoding::parse_position_words }, { "UNICODING", &DvipsEncoding::parse_unicoding_words } }; void DvipsEncoding::parse_word_group(Vector &words, int override, int wt, ErrorHandler *errh) { if (words.size() > 0) { int (DvipsEncoding::*method)(Vector &, int, ErrorHandler *) = word_types[wt].parsefunc; if ((this->*method)(words, override, errh) == -EPARSE) { Vector rewords; for (String *sp = words.begin(); sp != words.end(); sp++) { const char *s = sp->begin(), *ends = sp->end(); while (s != ends) { const char *word = s; if (*s == '{') { for (s++; s != ends && *s != '}'; s++) /* nada */; if (s != ends) s++; } else { bool x = retokenize_isword(*s); for (s++; s != ends && x == retokenize_isword(*s); s++) /* nada */; } rewords.push_back(sp->substring(word, s)); } } if ((this->*method)(rewords, override, errh) == -EPARSE) errh->error("parse error in %s", word_types[wt].name); } words.clear(); } } int DvipsEncoding::parse_words(const String &s, int override, int wt, ErrorHandler *errh) { Vector words; const char *data = s.data(); const char *end = s.end(); while (data < end) { while (data < end && isspace((unsigned char) *data)) data++; const char *first = data; while (data < end && !isspace((unsigned char) *data) && *data != ';') data++; if (data == first) { data++; // step past semicolon (or harmlessly past EOS) parse_word_group(words, override, wt, errh); } else words.push_back(s.substring(first, data)); } parse_word_group(words, override, wt, errh); return 0; } String DvipsEncoding::landmark(int line) const { StringAccum sa; sa << _printable_filename << ':' << line; return sa.take_string(); } static String trim_space(const String &s, int pos) { while (pos < s.length() && isspace((unsigned char) s[pos])) pos++; int epos = s.length(); for (int x = 0; x < 2; x++) { while (epos > pos && isspace((unsigned char) s[epos - 1])) epos--; if (epos == pos || s[epos - 1] != ';') break; epos--; } return s.substring(pos, epos - pos); } int DvipsEncoding::parse(String filename, bool ignore_ligkern, bool ignore_other, ErrorHandler *errh) { int before = errh->nerrors(); String s = read_file(filename, errh); if (errh->nerrors() != before) return -1; _filename = filename; _printable_filename = printable_filename(filename); _file_had_ligkern = false; int pos = 0, line = 1; // parse text String token = tokenize(s, pos, line); if (!token || token[0] != '/') return errh->lerror(landmark(line), "parse error, expected name"); _name = token.substring(1); _initial_comment = s.substring(0, pos - token.length()); if (tokenize(s, pos, line) != "[") return errh->lerror(landmark(line), "parse error, expected ["); while ((token = tokenize(s, pos, line)) && token[0] == '/') _e.push_back(token.substring(1)); _final_text = token + s.substring(pos); // now parse comments pos = 0, line = 1; Vector words; LandmarkErrorHandler lerrh(errh, ""); while ((token = comment_tokenize(s, pos, line))) if (token.length() >= 8 && memcmp(token.data(), "LIGKERN", 7) == 0 && isspace((unsigned char) token[7]) && !ignore_ligkern) { lerrh.set_landmark(landmark(line)); parse_words(token.substring(8), 1, WT_LIGKERN, &lerrh); } else if (token.length() >= 9 && memcmp(token.data(), "LIGKERNX", 8) == 0 && isspace((unsigned char) token[8]) && !ignore_ligkern) { lerrh.set_landmark(landmark(line)); parse_words(token.substring(9), 1, WT_LIGKERN, &lerrh); } else if (token.length() >= 10 && memcmp(token.data(), "UNICODING", 9) == 0 && isspace((unsigned char) token[9]) && !ignore_other) { lerrh.set_landmark(landmark(line)); parse_words(token.substring(10), 1, WT_UNICODING, &lerrh); } else if (token.length() >= 9 && memcmp(token.data(), "POSITION", 8) == 0 && isspace((unsigned char) token[8]) && !ignore_other) { lerrh.set_landmark(landmark(line)); parse_words(token.substring(9), 1, WT_POSITION, &lerrh); } else if (token.length() >= 13 && memcmp(token.data(), "CODINGSCHEME", 12) == 0 && isspace((unsigned char) token[12]) && !ignore_other) { _coding_scheme = trim_space(token, 13); if (_coding_scheme.length() > 39) lerrh.lwarning(landmark(line), "only first 39 chars of CODINGSCHEME are significant"); if (std::find(_coding_scheme.begin(), _coding_scheme.end(), '(') < _coding_scheme.end() || std::find(_coding_scheme.begin(), _coding_scheme.end(), ')') < _coding_scheme.end()) { lerrh.lerror(landmark(line), "CODINGSCHEME cannot contain parentheses"); _coding_scheme = String(); } } else if (token.length() >= 11 && memcmp(token.data(), "WARNMISSING", 11) == 0 && (token.length() == 11 || isspace((unsigned char) token[11])) && !ignore_other) { String value = trim_space(token, 11); if (value == "1" || value == "yes" || value == "true" || !value) _warn_missing = true; else if (value == "0" || value == "no" || value == "false") _warn_missing = false; else lerrh.lerror(landmark(line), "WARNMISSING command not understood"); } return 0; } int DvipsEncoding::parse_ligkern(const String &ligkern_text, int override, ErrorHandler *errh) { return parse_words(ligkern_text, override, WT_LIGKERN, errh); } int DvipsEncoding::parse_position(const String &position_text, int override, ErrorHandler *errh) { return parse_words(position_text, override, WT_POSITION, errh); } int DvipsEncoding::parse_unicoding(const String &unicoding_text, int override, ErrorHandler *errh) { return parse_words(unicoding_text, override, WT_UNICODING, errh); } void DvipsEncoding::bad_codepoint(int code, Metrics &metrics, HashMap &unencoded) { for (int i = 0; i < _lig.size(); i++) { Ligature &l = _lig[i]; if (l.c1 == code || l.c2 == code) l.join = 0; else if ((l.join & JT_ADDLIG) && l.d == code) l.join &= ~JT_LIGALL; } if (_warn_missing) { Vector garbage; bool unicodes_explicit = x_unicodes(_e[code], garbage); if (!unicodes_explicit || garbage.size() > 0) { Vector v; v.push_back(Setting(Setting::RULE, 500, 500)); v.push_back(Setting(Setting::SPECIAL, String("Warning: missing glyph '") + _e[code] + "'")); metrics.encode_virtual(code, _e[code], 0, v, true); unencoded.insert(_e[code], 1); } } } static inline Efont::OpenType::Glyph map_uni(uint32_t uni, const Efont::OpenType::Cmap &cmap, const Metrics &m) { if (uni == U_EMPTYSLOT) return m.emptyslot_glyph(); else return cmap.map_uni(uni); } bool DvipsEncoding::x_unicodes(PermString chname, Vector &unicodes) const { int i = _unicoding_map[chname]; if (i >= 0) { for (; _unicoding[i] > 0; i++) unicodes.push_back(_unicoding[i]); return true; } else { glyphname_unicode(chname, unicodes); return false; } } void DvipsEncoding::make_metrics(Metrics &metrics, const FontInfo &finfo, Secondary *secondary, bool literal, ErrorHandler *errh) { // first pass: without secondaries for (int code = 0; code < _e.size(); code++) { PermString chname = _e[code]; // common case: skip .notdef if (chname == dot_notdef) continue; // find first single Unicode glyph supported by the font Efont::OpenType::Glyph glyph = 0; uint32_t glyph_uni = 0; { Vector unicodes; (void) x_unicodes(chname, unicodes); Vector::iterator u = unicodes.begin(); while (u != unicodes.end() && glyph <= 0) { uint32_t this_uni = u[0]; ++u; if (u != unicodes.end()) { if (*u != GLYPHLIST_ALTERNATIVE) break; ++u; } glyph = map_uni(this_uni, *finfo.cmap, metrics); if (glyph_uni == 0 || glyph > 0) glyph_uni = this_uni; } } // find named glyph, if any Efont::OpenType::Glyph named_glyph = finfo.glyphid(chname); #if 0 // 2.May.2008: ff, fi, fl, ffi, and ffl might map to f_f, f_i, f_l, // f_f_i, and f_f_l if (!named_glyph && chname.length() > 0 && chname.length() <= 3 && chname[0] == 'f') { if (chname.equals("ff", 2)) named_glyph = finfo.glyphid("f_f"); else if (chname.equals("fi", 2)) named_glyph = finfo.glyphid("f_i"); else if (chname.equals("fl", 2)) named_glyph = finfo.glyphid("f_l"); else if (chname.equals("ffi", 2)) named_glyph = finfo.glyphid("f_f_i"); else if (chname.equals("ffl", 2)) named_glyph = finfo.glyphid("f_f_l"); } #endif // do not use a Unicode-mapped glyph if literal if (literal) glyph = named_glyph; // If we found a glyph, maybe use its named_glyph variant. if (glyph > 0 && named_glyph > 0 && std::find(chname.begin(), chname.end(), '.') < chname.end()) glyph = named_glyph; // assign slot if (glyph > 0) metrics.encode(code, glyph_uni, glyph); } // second pass: with secondaries for (int code = 0; code < _e.size(); code++) { // skip already-encoded characters and .notdef if (literal || metrics.glyph(code) > 0 || _e[code] == dot_notdef) continue; PermString chname = _e[code]; // find all Unicodes Vector unicodes; bool unicodes_explicit = x_unicodes(chname, unicodes); // find named glyph, if any Efont::OpenType::Glyph named_glyph = finfo.glyphid(chname); // 1. We were not able to find the glyph using Unicode. // 2. There might be a named_glyph. // May need to try secondaries later. Store this slot. // Try secondaries, if there's explicit unicoding or no named_glyph. if (unicodes_explicit || named_glyph <= 0) for (uint32_t *u = unicodes.begin(); u != unicodes.end(); ) { uint32_t *endu = u + 1; while (endu != unicodes.end() && *endu != GLYPHLIST_ALTERNATIVE) ++endu; if (secondary->encode_uni(code, chname, u, endu, metrics, errh)) goto encoded; u = (endu == unicodes.end() ? endu : endu + 1); } // 1. We were not able to find the glyph using Unicode or secondaries. // 2. There might be a named_glyph. // Use named glyph, if any. Special case for "UNICODING foo =: ;", // which should turn off the character (even if a named_glyph exists), // UNLESS the glyph was explicitly requested. if (named_glyph > 0 && (!unicodes_explicit || unicodes.size() > 0 || (_encoding_required.size() > code && _encoding_required[code]))) { uint32_t uni = 0; if (unicodes.size() == 1 || (unicodes.size() > 0 && unicodes[1] == GLYPHLIST_ALTERNATIVE)) uni = unicodes[0]; metrics.encode(code, uni, named_glyph); } encoded: /* all set */; } // add altselector if (_altselector_char >= 0 && _altselector_char < _e.size()) { metrics.add_altselector_code(_altselector_char, 0); if (metrics.glyph(_altselector_char) <= 0 && !literal) (void) secondary->encode_uni(_altselector_char, "", U_ALTSELECTOR, metrics, errh); } // final pass: complain HashMap unencoded_map; for (int code = 0; code < _e.size(); code++) if (_e[code] != dot_notdef && metrics.glyph(code) <= 0) bad_codepoint(code, metrics, unencoded_map); Vector unencoded; for (HashMap::iterator it = unencoded_map.begin(); it; ++it) unencoded.push_back(it.key()); if (unencoded.size() == 1) { errh->warning("%<%s%> glyph not found in font", unencoded[0].c_str()); errh->message("(This glyph will appear as a blot and cause warnings if used.)"); } else if (unencoded.size() > 1) { std::sort(unencoded.begin(), unencoded.end()); StringAccum sa; for (const String* a = unencoded.begin(); a < unencoded.end(); a++) sa << *a << ' '; sa.pop_back(); sa.append_break_lines(sa.take_string(), 68, " "); sa.pop_back(); errh->warning("%d glyphs not found in font:", unencoded.size()); errh->message("%s\n(These glyphs will appear as blots and cause warnings if used.)", sa.c_str()); } metrics.set_coding_scheme(_coding_scheme); } void DvipsEncoding::make_base_mappings(Vector &mappings, const FontInfo &finfo) { mappings.clear(); for (int code = 0; code < _e.size(); code++) { PermString chname = _e[code]; // common case: skip .notdef if (chname == dot_notdef) continue; // find named glyph Efont::OpenType::Glyph named_glyph = finfo.glyphid(chname); if (named_glyph > 0) { if (mappings.size() <= named_glyph) mappings.resize(named_glyph + 1, -1); mappings[named_glyph] = code; } } } void DvipsEncoding::apply_ligkern_lig(Metrics &metrics, ErrorHandler *errh) const { assert((int)J_ALL == (int)Metrics::CODE_ALL); for (const Ligature *l = _lig.begin(); l < _lig.end(); l++) { if (l->c1 < 0 || l->c2 < 0 || l->join < 0 || !(l->join & JT_LIG)) continue; metrics.remove_ligatures(l->c1, l->c2); if (!(l->join & JT_ADDLIG)) /* nada */; else if ((l->join & JT_LIGALL) == JL_LIG) metrics.add_ligature(l->c1, l->c2, l->d); else if ((l->join & JT_LIGALL) == JL_LIGC) metrics.add_ligature(l->c1, l->c2, metrics.pair_code(l->d, l->c2)); else if ((l->join & JT_LIGALL) == JL_CLIG) metrics.add_ligature(l->c1, l->c2, metrics.pair_code(l->c1, l->d)); else { static int complex_join_warning = 0; if (!complex_join_warning) { errh->warning("complex LIGKERN ligature removed (I only support %<=:%>, %<=:|%>, and %<|=:%>)"); complex_join_warning = 1; } } } } void DvipsEncoding::apply_ligkern_kern(Metrics &metrics, ErrorHandler *) const { assert((int)J_ALL == (int)Metrics::CODE_ALL); for (const Ligature *l = _lig.begin(); l < _lig.end(); l++) if (l->c1 >= 0 && l->c2 >= 0 && (l->join & JT_KERN)) metrics.set_kern(l->c1, l->c2, l->k); } void DvipsEncoding::apply_position(Metrics &metrics, ErrorHandler *) const { for (const Ligature *l = _pos.begin(); l < _pos.end(); l++) if (l->c1 >= 0) metrics.add_single_positioning(l->c1, l->c2, l->join, l->k); } lcdf-typetools-2.108/otftotfm/automatic.cc0000644000175000017500000006544713423375330015577 00000000000000/* automatic.{cc,hh} -- code for automatic mode and interfacing with kpathsea * * Copyright (c) 2003-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #include #include "automatic.hh" #include "kpseinterface.h" #include "util.hh" #include #include #include #include #include #if HAVE_UNISTD_H # include #endif #include #include #if HAVE_SYS_TIME_H # include #endif #if HAVE_SYS_WAIT_H # include #endif #include #include #if HAVE_FCNTL_H # include #endif #include #ifdef WIN32 # define mkdir(dir, access) mkdir(dir) # define COPY_CMD "copy" # define CMD_SEP "&" #else # define COPY_CMD "cp" # define CMD_SEP ";" #endif /* kpathsea may already have defined this */ #ifndef DEV_NULL # ifdef WIN32 # define DEV_NULL "NUL" # else # define DEV_NULL "/dev/null" # endif #endif #if HAVE_AUTO_T1DOTLESSJ enum { T1DOTLESSJ_EXIT_J_NODOT = 2 }; #endif static String odir[NUMODIR]; static String typeface; static String vendor; static String map_file; #define DEFAULT_VENDOR "lcdftools" #define DEFAULT_TYPEFACE "unknown" static const struct { const char *name; const char *envvar; const char *texdir; } odir_info[] = { { "encoding", "ENCODINGDESTDIR", "#fonts/enc/dvips/@#dvips/@" }, { "TFM", "TFMDESTDIR", "fonts/tfm/%" }, { "PL", "PLDESTDIR", "fonts/pl/%" }, { "VF", "VFDESTDIR", "fonts/vf/%" }, { "VPL", "VPLDESTDIR", "fonts/vpl/%" }, { "Type 1", "T1DESTDIR", "fonts/type1/%" }, { "DVIPS map", "DVIPS directory", "#fonts/map/dvips/@#dvips/@" }, { "DVIPS updmap", "DVIPS directory", "dvips" }, { "TrueType", "TTFDESTDIR", "fonts/truetype/%" }, { "OpenType", "OPENTYPEDESTDIR", "fonts/opentype/%" }, { "Type 42", "T42DESTDIR", "fonts/type42/%" } }; #if HAVE_KPATHSEA static String odir_kpathsea[NUMODIR]; static bool writable_texdir_tried = false; static String writable_texdir; // always ends with directory separator static int tds_1_1 = -1; static bool mktexupd_tried = false; static String mktexupd; static String kpsei_string(char* x) { String s(x); free((void*)x); return s; } static void look_for_writable_texdir(const char *path_variable, bool create) { String path = kpsei_string(kpsei_path_expand(path_variable)); while (path && !writable_texdir) { const char* colon = std::find(path.begin(), path.end(), kpsei_env_sep_char); String texdir = path.substring(path.begin(), colon); path = path.substring(colon + 1, path.end()); if (access(texdir.c_str(), W_OK) >= 0) writable_texdir = texdir; else if (create && errno != EACCES && mkdir(texdir.c_str(), 0777) >= 0) // create file if it doesn't exist already writable_texdir = texdir; } if (writable_texdir && writable_texdir.back() != '/') writable_texdir += "/"; } static void find_writable_texdir(ErrorHandler *errh, const char *) { look_for_writable_texdir("$TEXMFVAR", true); if (!writable_texdir) look_for_writable_texdir("$VARTEXMF", false); if (!writable_texdir) look_for_writable_texdir("$TEXMF", false); if (!writable_texdir) { errh->warning("no writable directory found in $TEXMFVAR or $TEXMF"); errh->message("(You probably need to set your TEXMF environment variable; see\n\ the manual for more information. The current TEXMF path is\n\ %<%s%>.)", kpsei_string(kpsei_path_expand("$TEXMF")).c_str()); } writable_texdir_tried = true; } static String get_vendor() { return (vendor ? vendor : String(DEFAULT_VENDOR)); } static String get_typeface() { return (typeface ? typeface : String(DEFAULT_TYPEFACE)); } #endif bool set_vendor(const String &s) { bool had = (bool) vendor; vendor = s; return !had; } bool set_typeface(const String &s, bool override) { bool had = (bool) typeface; if (!had || override) typeface = s; return !had; } String getodir(int o, ErrorHandler *errh) { assert(o >= 0 && o < NUMODIR); if (!odir[o] && automatic && odir_info[o].envvar) odir[o] = getenv(odir_info[o].envvar); #if HAVE_KPATHSEA if (!odir[o] && automatic && !writable_texdir_tried) find_writable_texdir(errh, odir_info[o].name); if (!odir[o] && automatic && writable_texdir) { String suffix = odir_info[o].texdir; // May need to behave differently on TDS 1.1 rather than TDS 1.0. if (suffix[0] == '#') { // check type of TDS if (tds_1_1 < 0) { // using a procedure suggested by Olaf Weber String encfonts = kpsei_string(kpsei_path_expand("$TEXMFMAIN/fonts/enc")); if (!encfonts) encfonts = kpsei_string(kpsei_path_expand("$TEXMFDIST/fonts/enc")); tds_1_1 = (encfonts != String()); } if (tds_1_1 == 0) suffix = suffix.substring(std::find(suffix.begin() + 1, suffix.end(), '#') + 1, suffix.end()); else suffix = suffix.substring(suffix.begin() + 1, std::find(suffix.begin() + 1, suffix.end(), '#')); } String dir = writable_texdir + suffix; if (dir.back() == '%') dir = dir.substring(0, -1) + get_vendor() + "/" + get_typeface(); else if (dir.back() == '@') dir = dir.substring(0, -1) + get_vendor(); // create parent directories as appropriate int slash = writable_texdir.length() - 1; while (access(dir.c_str(), F_OK) < 0 && slash < dir.length()) { if ((slash = dir.find_left('/', slash + 1)) < 0) slash = dir.length(); String subdir = dir.substring(0, slash); if (access(subdir.c_str(), F_OK) < 0 && !no_create && mkdir(subdir.c_str(), 0777) < 0) goto kpathsea_done; } // that's our answer odir[o] = dir; odir_kpathsea[o] = dir; } kpathsea_done: #endif if (!odir[o]) { if (automatic) { errh->warning("%s not specified, placing %s files in %<.%>", odir_info[o].envvar, odir_info[o].name); #if !HAVE_KPATHSEA static int kpathsea_warning = 0; if (++kpathsea_warning == 1) errh->message("(This version of otftotfm lacks $TEXMF directory support.)"); #endif } odir[o] = "."; } while (odir[o].length() && odir[o].back() == '/') odir[o] = odir[o].substring(0, -1); if (verbose) errh->message("placing %s files in %<%s%>", odir_info[o].name, odir[o].c_str()); return odir[o]; } void setodir(int o, const String &value) { assert(o >= 0 && o < NUMODIR); odir[o] = value; } const char * odirname(int o) { if (o == NUMODIR) { return "default"; } else { assert(o >= 0 && o < NUMODIR); return odir_info[o].name; } } #if HAVE_KPATHSEA static bool file_in_kpathsea_odir(int o, const String &file) { return odir_kpathsea[o] && file.length() > odir[o].length() && memcmp(file.data(), odir[o].data(), odir[o].length()) == 0 && file[odir[o].length()] == '/'; } #endif void update_odir(int o, String file, ErrorHandler *errh) { assert(o >= 0 && o < NUMODIR); #if HAVE_KPATHSEA if (file.find_left('/') < 0) file = odir[o] + "/" + file; // exit if this directory was not found via kpathsea, or the file is not // in the kpathsea directory if (!file_in_kpathsea_odir(o, file)) return; assert(writable_texdir && writable_texdir.length() <= odir[o].length() && memcmp(file.data(), writable_texdir.data(), writable_texdir.length()) == 0); // divide the filename into portions // file == writable_texdir + directory + file file = file.substring(writable_texdir.length()); while (file && file[0] == '/') file = file.substring(1); int last_slash = file.find_right('/'); String directory = (last_slash >= 0 ? file.substring(0, last_slash) : String()); file = file.substring(last_slash >= 0 ? last_slash + 1 : 0); if (!file) // no filename to update return; // return if nocreate if (no_create) { errh->message("would update %sls-R for %s/%s", writable_texdir.c_str(), directory.c_str(), file.c_str()); return; } else if (verbose) errh->message("updating %sls-R for %s/%s", writable_texdir.c_str(), directory.c_str(), file.c_str()); // try to update ls-R ourselves, rather than running mktexupd -- // mktexupd's runtime is painful: a half second to update a file String ls_r = writable_texdir + "ls-R"; bool success = false; if (access(ls_r.c_str(), R_OK) >= 0) // make sure it already exists if (FILE *f = fopen(ls_r.c_str(), "a")) { fprintf(f, "./%s:\n%s\n", directory.c_str(), file.c_str()); success = true; fclose(f); } // otherwise, run mktexupd if (!success && writable_texdir.find_left('\'') < 0 && directory.find_left('\'') < 0 && file.find_left('\'') < 0) { // look for mktexupd script if (!mktexupd_tried) { mktexupd = kpsei_string(kpsei_find_file("mktexupd", KPSEI_FMT_WEB2C)); mktexupd_tried = true; } // run script if (mktexupd) { String command = mktexupd + " " + shell_quote(writable_texdir + directory) + " " + shell_quote(file); int retval = system(command.c_str()); if (retval == 127) errh->error("could not run %<%s%>", command.c_str()); else if (retval < 0) errh->error("could not run %<%s%>: %s", command.c_str(), strerror(errno)); else if (retval != 0) errh->error("%<%s%> failed", command.c_str()); } } #else (void) file, (void) errh; #endif } bool set_map_file(const String &s) { bool had = (bool) map_file; map_file = s; return !had; } String installed_type1(const String &otf_filename, const String &ps_fontname, bool allow_generate, ErrorHandler *errh) { (void) otf_filename, (void) allow_generate, (void) errh; if (!ps_fontname) return String(); #if HAVE_KPATHSEA # if HAVE_AUTO_CFFTOT1 if (!(force && allow_generate && otf_filename && otf_filename != "-" && getodir(O_TYPE1, errh))) { # endif // look for .pfb and .pfa String file, path; if ((file = ps_fontname + ".pfb", path = kpsei_string(kpsei_find_file(file.c_str(), KPSEI_FMT_TYPE1))) || (file = ps_fontname + ".pfa", path = kpsei_string(kpsei_find_file(file.c_str(), KPSEI_FMT_TYPE1)))) { if (path == "./" + file || path == file) { if (verbose) errh->message("ignoring Type 1 file %s found with kpathsea in %<.%>", path.c_str()); } else { if (verbose) errh->message("Type 1 file %s found with kpathsea at %s", file.c_str(), path.c_str()); return path; } } # if HAVE_AUTO_CFFTOT1 } # endif #endif #if HAVE_AUTO_CFFTOT1 // if not found, and can generate on the fly, run cfftot1 if (allow_generate && otf_filename && otf_filename != "-" && getodir(O_TYPE1, errh)) { String pfb_filename = odir[O_TYPE1] + "/" + ps_fontname + ".pfb"; if (pfb_filename.find_left('\'') >= 0 || otf_filename.find_left('\'') >= 0) return String(); String command = "cfftot1 " + shell_quote(otf_filename) + " -n " + shell_quote(ps_fontname) + " " + shell_quote(pfb_filename); int retval = mysystem(command.c_str(), errh); if (retval == 127) errh->error("could not run %<%s%>", command.c_str()); else if (retval < 0) errh->error("could not run %<%s%>: %s", command.c_str(), strerror(errno)); else if (retval != 0) errh->error("%<%s%> failed", command.c_str()); if (retval == 0) { update_odir(O_TYPE1, pfb_filename, errh); return pfb_filename; } } #endif return String(); } String installed_type1_dotlessj(const String &otf_filename, const String &ps_fontname, bool allow_generate, ErrorHandler *errh) { (void) otf_filename, (void) allow_generate, (void) errh; if (!ps_fontname) return String(); if (verbose) errh->message("searching for dotless-j font for %s", ps_fontname.c_str()); String j_ps_fontname = ps_fontname + "LCDFJ"; #if HAVE_KPATHSEA # if HAVE_AUTO_T1DOTLESSJ if (!(force && allow_generate && getodir(O_TYPE1, errh))) { # endif // look for existing .pfb or .pfa String file, path; if ((file = j_ps_fontname + ".pfb", path = kpsei_string(kpsei_find_file(file.c_str(), KPSEI_FMT_TYPE1))) || (file = j_ps_fontname + ".pfa", path = kpsei_string(kpsei_find_file(file.c_str(), KPSEI_FMT_TYPE1)))) { // ignore versions in the current directory if (path == "./" + file || path == file) { if (verbose) errh->message("ignoring Type 1 file %s found with kpathsea in %<.%>", path.c_str()); } else { if (verbose) errh->message("Type 1 file %s found with kpathsea at %s", file.c_str(), path.c_str()); return path; } } # if HAVE_AUTO_T1DOTLESSJ } # endif #endif #if HAVE_AUTO_T1DOTLESSJ // if not found, and can generate on the fly, try running t1dotlessj if (allow_generate && getodir(O_TYPE1, errh)) { if (String base_filename = installed_type1(otf_filename, ps_fontname, allow_generate, errh)) { String pfb_filename = odir[O_TYPE1] + "/" + j_ps_fontname + ".pfb"; if (pfb_filename.find_left('\'') >= 0 || base_filename.find_left('\'') >= 0) return String(); String command = "t1dotlessj " + shell_quote(base_filename) + " -n " + shell_quote(j_ps_fontname) + " " + shell_quote(pfb_filename); int retval = mysystem(command.c_str(), errh); if (retval == 127) errh->warning("could not run %<%s%>", command.c_str()); else if (retval < 0) errh->warning("could not run %<%s%>: %s", command.c_str(), strerror(errno)); else if (WEXITSTATUS(retval) == T1DOTLESSJ_EXIT_J_NODOT) return String("\0", 1); else if (retval != 0) errh->warning("%<%s%> failed (%d)", command.c_str(), retval); if (retval == 0) { update_odir(O_TYPE1, pfb_filename, errh); return pfb_filename; } else errh->warning("output font will not contain a dotless-j character"); } } #endif return String(); } String installed_truetype(const String &ttf_filename, bool allow_generate, ErrorHandler *errh) { String file = pathname_filename(ttf_filename); #if HAVE_KPATHSEA if (!(force && allow_generate && ttf_filename && ttf_filename != "-" && getodir(O_TRUETYPE, errh))) { if (String path = kpsei_string(kpsei_find_file(file.c_str(), KPSEI_FMT_TRUETYPE))) { if (path == "./" + file || path == file) { if (verbose) errh->message("ignoring TrueType file %s found with kpathsea in %<.%>", path.c_str()); } else { if (verbose) errh->message("TrueType file %s found with kpathsea at %s", file.c_str(), path.c_str()); return path; } } } #endif // perhaps generate type 42 in the future, for now just copy if (allow_generate && ttf_filename && ttf_filename != "-" && getodir(O_TRUETYPE, errh)) { String installed_ttf_filename = odir[O_TRUETYPE] + "/" + file; if (installed_ttf_filename.find_left('\'') >= 0 || installed_ttf_filename.find_left('\"') >= 0) return String(); int retval; if (!same_filename(ttf_filename, installed_ttf_filename)) { String command = COPY_CMD " " + shell_quote(ttf_filename) + " " + shell_quote(installed_ttf_filename); retval = mysystem(command.c_str(), errh); if (retval == 127) errh->error("could not run %<%s%>", command.c_str()); else if (retval < 0) errh->error("could not run %<%s%>: %s", command.c_str(), strerror(errno)); else if (retval != 0) errh->error("%<%s%> failed", command.c_str()); } else { if (verbose) errh->message("TrueType file %s already located in output directory", installed_ttf_filename.c_str()); retval = 0; } if (retval == 0) { update_odir(O_TRUETYPE, installed_ttf_filename, errh); return installed_ttf_filename; } } return String(); } String installed_type42(const String &ttf_filename, const String &ps_fontname, bool allow_generate, ErrorHandler *errh) { (void) allow_generate, (void) ttf_filename, (void) errh; if (!ps_fontname) return String(); #if HAVE_KPATHSEA # if HAVE_AUTO_TTFTOTYPE42 if (!(force && allow_generate && ttf_filename && ttf_filename != "-" && getodir(O_TYPE42, errh))) { # endif // look for .pfb and .pfa String file, path; if ((file = ps_fontname + ".t42", path = kpsei_string(kpsei_find_file(file.c_str(), KPSEI_FMT_TYPE42)))) { if (path == "./" + file || path == file) { if (verbose) errh->message("ignoring Type 42 file %s found with kpathsea in %<.%>", path.c_str()); } else { if (verbose) errh->message("Type 42 file %s found with kpathsea at %s", file.c_str(), path.c_str()); return path; } } # if HAVE_AUTO_TTFTOTYPE42 } # endif #endif #if HAVE_AUTO_TTFTOTYPE42 // if not found, and can generate on the fly, run ttftotype42 if (allow_generate && ttf_filename && ttf_filename != "-" && getodir(O_TYPE42, errh)) { String t42_filename = odir[O_TYPE42] + "/" + ps_fontname + ".t42"; if (t42_filename.find_left('\'') >= 0 || ttf_filename.find_left('\'') >= 0) return String(); String command = "ttftotype42 " + shell_quote(ttf_filename) + " " + shell_quote(t42_filename); int retval = mysystem(command.c_str(), errh); if (retval == 127) errh->error("could not run %<%s%>", command.c_str()); else if (retval < 0) errh->error("could not run %<%s%>: %s", command.c_str(), strerror(errno)); else if (retval != 0) errh->error("%<%s%> failed", command.c_str()); if (retval == 0) { update_odir(O_TYPE42, t42_filename, errh); return t42_filename; } } #endif return String(); } int update_autofont_map(const String &fontname, String mapline, ErrorHandler *errh) { #if HAVE_KPATHSEA if (automatic && !map_file && getodir(O_MAP, errh)) map_file = odir[O_MAP] + "/" + get_vendor() + ".map"; #endif if (map_file == "" || map_file == "-") fputs(mapline.c_str(), stdout); else { // report no_create/verbose if (no_create) { errh->message("would update %s for %s", map_file.c_str(), String(fontname).c_str()); return 0; } else if (verbose) errh->message("updating %s for %s", map_file.c_str(), String(fontname).c_str()); int fd = open(map_file.c_str(), O_RDWR | O_CREAT, 0666); if (fd < 0) return errh->lerror(map_file, "%s", strerror(errno)); FILE *f = fdopen(fd, "r+"); // NB: also change encoding logic if you change this code #if defined(F_SETLKW) && defined(HAVE_FTRUNCATE) { struct flock lock; lock.l_type = F_WRLCK; lock.l_whence = SEEK_SET; lock.l_start = 0; lock.l_len = 0; int result; while ((result = fcntl(fd, F_SETLKW, &lock)) < 0 && errno == EINTR) /* try again */; if (result < 0) { result = errno; fclose(f); return errh->error("locking %s: %s", map_file.c_str(), strerror(result)); } } #endif // read old data from map file StringAccum sa; int amt; do { if (char *x = sa.reserve(8192)) { amt = fread(x, 1, 8192, f); sa.adjust_length(amt); } else amt = 0; } while (amt != 0); if (!feof(f)) return errh->error("%s: %s", map_file.c_str(), strerror(errno)); String text = sa.take_string(); // add comment if necessary bool created = (!text); if (created) text = "% Automatically maintained by otftotfm or other programs. Do not edit.\n\n"; if (text.back() != '\n') text += "\n"; // append old encodings int fl = 0; int nl = text.find_left('\n') + 1; bool changed = created; while (fl < text.length()) { if (fl + fontname.length() + 1 < nl && memcmp(text.data() + fl, fontname.data(), fontname.length()) == 0 && text[fl + fontname.length()] == ' ') { // found the old name if (text.substring(fl, nl - fl) == mapline) { // duplicate of old name, don't change it fclose(f); if (verbose) errh->message("%s unchanged", map_file.c_str()); return 0; } else { text = text.substring(0, fl) + text.substring(nl); nl = fl; changed = true; } } fl = nl; nl = text.find_left('\n', fl) + 1; } if (!mapline && !changed) { // special case: empty mapline, unchanged file if (verbose) errh->message("%s unchanged", map_file.c_str()); } else { // add our text text += mapline; // rewind file #if HAVE_FTRUNCATE rewind(f); if (ftruncate(fd, 0) < 0) #endif { fclose(f); f = fopen(map_file.c_str(), "w"); fd = fileno(f); } // write data ignore_result(fwrite(text.data(), 1, text.length(), f)); } fclose(f); // inform about the new file if necessary if (created) update_odir(O_MAP, map_file, errh); #if HAVE_KPATHSEA && !WIN32 // run 'updmap' if present String updmap_prog = output_flags & G_UPDMAP_USER ? "updmap-user" : "updmap-sys"; String updmap_dir, updmap_file; if (automatic && (output_flags & G_UPDMAP)) updmap_dir = getodir(O_MAP_PARENT, errh); if (updmap_dir && (updmap_file = updmap_dir + "/" + updmap_prog) && access(updmap_file.c_str(), X_OK) >= 0) { // want to run `updmap` from its directory, can't use system() if (verbose) errh->message("running %s", updmap_file.c_str()); pid_t child = fork(); if (child < 0) errh->fatal("%s during fork", strerror(errno)); else if (child == 0) { // change to updmap directory, run it if (chdir(updmap_dir.c_str()) < 0) errh->fatal("%s: %s during chdir", updmap_dir.c_str(), strerror(errno)); if (execl(output_flags & G_UPDMAP_USER ? "./updmap-user" : "./updmap-sys", updmap_file.c_str(), (const char*) 0) < 0) errh->fatal("%s: %s during exec", updmap_file.c_str(), strerror(errno)); exit(1); // should never get here } # if HAVE_WAITPID // wait for updmap to finish int status; while (1) { pid_t answer = waitpid(child, &status, 0); if (answer >= 0) break; else if (errno != EINTR) errh->fatal("%s during wait", strerror(errno)); } if (!WIFEXITED(status)) errh->warning("%s exited abnormally", updmap_file.c_str()); else if (WEXITSTATUS(status) != 0) errh->warning("%s exited with status %d", updmap_file.c_str(), WEXITSTATUS(status)); # else # error "need waitpid() support: report this bug to the maintainer" # endif goto ran_updmap; } # if HAVE_AUTO_UPDMAP // run system updmap if (output_flags & G_UPDMAP) { String filename = map_file; int slash = filename.find_right('/'); if (slash >= 0) filename = filename.substring(slash + 1); String redirect = verbose ? " 1>&2" : " >" DEV_NULL " 2>&1"; String command = updmap_prog + " --nomkmap --enable Map " + shell_quote(filename) + redirect + CMD_SEP " " + updmap_prog + redirect; int retval = mysystem(command.c_str(), errh); if (retval == 127) errh->warning("could not run %<%s%>", command.c_str()); else if (retval < 0) errh->warning("could not run %<%s%>: %s", command.c_str(), strerror(errno)); else if (retval != 0) errh->warning("%<%s%> exited with status %d;\nrun it manually to check for errors", command.c_str(), WEXITSTATUS(retval)); goto ran_updmap; } # endif if (verbose) errh->message("not running updmap"); ran_updmap: ; #endif } return 0; } String locate_encoding(String encfile, ErrorHandler *errh, bool literal) { if (!encfile || encfile == "-") return encfile; if (!literal) { int slash = encfile.find_right('/'); int dot = encfile.find_left('.', slash >= 0 ? slash : 0); if (dot < 0) if (String file = locate_encoding(encfile + ".enc", errh, true)) return file; } #if HAVE_KPATHSEA if (String file = kpsei_string(kpsei_find_file(encfile.c_str(), KPSEI_FMT_ENCODING))) { if (verbose) errh->message("encoding file %s found with kpathsea at %s", encfile.c_str(), file.c_str()); return file; } else if (verbose) errh->message("encoding file %s not found with kpathsea", encfile.c_str()); #endif if (access(encfile.c_str(), R_OK) >= 0) return encfile; else return String(); } lcdf-typetools-2.108/otftotfm/glyphfilter.hh0000644000175000017500000000610313423375330016134 00000000000000#ifndef OTFTOTFM_GLYPHFILTER_HH #define OTFTOTFM_GLYPHFILTER_HH #include #include class Metrics; class GlyphFilter { public: GlyphFilter() : _sorted(true) { } operator bool() const { return _patterns.size() != 0; } inline bool allow_substitution(Efont::OpenType::Glyph glyph, const Vector& glyph_names, uint32_t unicode) const; inline bool allow_alternate(Efont::OpenType::Glyph glyph, const Vector& glyph_names, uint32_t unicode) const; void add_substitution_filter(const String&, bool is_exclude, ErrorHandler*); void add_alternate_filter(const String&, bool is_exclude, ErrorHandler*); friend bool operator==(const GlyphFilter&, const GlyphFilter&); inline bool check_eq(GlyphFilter&); // may alter both GlyphFilters GlyphFilter& operator+=(const GlyphFilter&); void unparse(StringAccum&) const; struct Pattern { uint16_t type; uint16_t data; union { struct { int mask; int value; } uniprop; struct { uint32_t low; uint32_t high; } unirange; } u; String pattern; Pattern(uint16_t type); static int compare(const Pattern&, const Pattern&); }; private: enum { T_EXCLUDE = 1, T_NEGATE = 2, T_TYPEMASK = 3, T_SRC = 0, T_DST = 4 }; enum { D_NAME, D_UNIPROP, D_UNIRANGE }; Vector _patterns; bool _sorted; bool allow(Efont::OpenType::Glyph glyph, const Vector& glyph_names, uint32_t unicode, int ptype) const; void add_pattern(const String&, int ptype, ErrorHandler*); void sort(); }; inline bool GlyphFilter::allow_substitution(Efont::OpenType::Glyph glyph, const Vector& glyph_names, uint32_t unicode) const { return (!_patterns.size() || allow(glyph, glyph_names, unicode, T_SRC)); } inline bool GlyphFilter::allow_alternate(Efont::OpenType::Glyph glyph, const Vector& glyph_names, uint32_t unicode) const { return (!_patterns.size() || allow(glyph, glyph_names, unicode, T_DST)); } inline bool operator==(const GlyphFilter::Pattern& a, const GlyphFilter::Pattern& b) { return a.type == b.type && a.data == b.data && a.u.unirange.low == b.u.unirange.low && a.u.unirange.high == b.u.unirange.high && a.pattern == b.pattern; } inline bool operator<(const GlyphFilter::Pattern& a, const GlyphFilter::Pattern& b) { return GlyphFilter::Pattern::compare(a, b) < 0; } inline bool operator!=(const GlyphFilter::Pattern& a, const GlyphFilter::Pattern& b) { return !(a == b); } bool operator==(const GlyphFilter&, const GlyphFilter&); inline bool operator!=(const GlyphFilter& a, const GlyphFilter& b) { return !(a == b); } inline bool GlyphFilter::check_eq(GlyphFilter& o) { sort(); o.sort(); return *this == o; } GlyphFilter operator+(const GlyphFilter&, const GlyphFilter&); inline StringAccum& operator<<(StringAccum& sa, const GlyphFilter& gf) { gf.unparse(sa); return sa; } #endif lcdf-typetools-2.108/otftotfm/metrics.hh0000644000175000017500000002155513423375330015261 00000000000000#ifndef OTFTOTFM_METRICS_HH #define OTFTOTFM_METRICS_HH #include #include #include "setting.hh" namespace Efont { class CharstringProgram; } class DvipsEncoding; class GlyphFilter; class Metrics { public: typedef int Code; typedef Efont::OpenType::Glyph Glyph; enum { VIRTUAL_GLYPH = 0x10000 }; typedef Efont::OpenType::Substitution Substitution; typedef Efont::OpenType::Positioning Positioning; Metrics(const Efont::CharstringProgram *, int nglyphs); ~Metrics(); void check() const; Glyph boundary_glyph() const { return _boundary_glyph; } Glyph emptyslot_glyph() const { return _emptyslot_glyph; } String coding_scheme() const { return _coding_scheme; } void set_coding_scheme(const String &s) { _coding_scheme = s; } int design_units() const { return _design_units; } int units_per_em() const { return _units_per_em; } void set_design_units(int du) { _design_units = du; } int n_mapped_fonts() const { return _mapped_fonts.size();} const Efont::CharstringProgram *mapped_font(int i) const { return _mapped_fonts[i]; } const String &mapped_font_name(int i) const { return _mapped_font_names[i]; } int add_mapped_font(const Efont::CharstringProgram *, const String &); inline int encoding_size() const { return _encoding.size(); } inline bool valid_code(Code) const; inline bool nonvirtual_code(Code) const; PermString code_name(Code) const; inline const char *code_str(Code) const; inline Glyph glyph(Code code) const; inline uint32_t unicode(Code code) const; inline Code encoding(Glyph g, Code after) const; Code unicode_encoding(uint32_t uni) const; Code force_encoding(Glyph g, int lookup_source = -1); void encode(Code code, uint32_t uni, Glyph g); void encode_virtual(Code, PermString, uint32_t uni, const Vector &, bool base_char); void add_altselector_code(Code, int altselector_type); bool altselectors() const { return _altselectors.size() > 0; } inline bool was_base_glyph(Code) const; inline Code base_code(Code) const; inline Glyph base_glyph(Code) const; bool base_glyphs(Vector &, int size) const; void add_ligature(Code in1, Code in2, Code out); Code pair_code(Code, Code, int lookup_source = -1); void add_kern(Code in1, Code in2, int kern); void set_kern(Code in1, Code in2, int kern); void add_single_positioning(Code, int pdx, int pdy, int adx); enum { CODE_ALL = 0x7FFFFFFF }; void remove_ligatures(Code in1, Code in2); int reencode_right_ligkern(Code old_in2, Code new_in2); int apply(const Vector&, bool allow_single, int lookup, const GlyphFilter&, const Vector& glyph_names); void apply_alternates(const Vector&, int lookup, const GlyphFilter&, const Vector& glyph_names); int apply(const Vector&); void apply_base_encoding(const String &font_name, const DvipsEncoding &, const Vector &mapping); void cut_encoding(int size); void shrink_encoding(int size, const DvipsEncoding &, ErrorHandler *); void make_base(int size); bool need_virtual(int size) const; bool need_base(); enum SettingMode { SET_NONE = 0, SET_KEEP = 1, SET_INTERMEDIATE = 3 }; bool setting(Code, Vector &, SettingMode = SET_NONE) const; int ligatures(Code in1, Vector &in2, Vector &out, Vector &context) const; int kerns(Code in1, Vector &in2, Vector &kern) const; int kern(Code in1, Code in2) const; void unparse() const; struct Ligature { Code in2; Code out; Ligature(Code in2_, Code out_) : in2(in2_), out(out_) { } }; struct Kern { Code in2; int kern; Kern(Code in2_, int kern_) : in2(in2_), kern(kern_) { } }; struct VirtualChar { PermString name; Vector setting; }; struct Ligature3 { Code in1; Code in2; Code out; Ligature3(Code in1_, Code in2_, Code out_) : in1(in1_), in2(in2_), out(out_) { } String unparse(const Metrics& m) const; }; private: struct Char { Glyph glyph; Code base_code; uint32_t unicode; Vector ligatures; Vector kerns; VirtualChar *virtual_char; int pdx; int pdy; int adx; Code built_in1; Code built_in2; int lookup_source; enum { BUILT = 1, INTERMEDIATE = 2, CONTEXT_ONLY = 4, LIVE = 8, BASE_LIVE = 16, BASE_REP = 32, IS_FF = 64 }; int flags; Char() : virtual_char(0) { clear(); } void clear(); void swap(Char &); bool visible() const { return glyph != 0; } bool visible_base() const { return glyph != 0 && glyph != VIRTUAL_GLYPH; } bool flag(int f) const { return (flags & f) != 0; } inline bool base_glyph() const; bool context_setting(Code in1, Code in2) const; }; Vector _encoding; mutable Vector _emap; Glyph _boundary_glyph; Glyph _emptyslot_glyph; Vector _altselectors; String _coding_scheme; int _design_units; int _units_per_em; bool _liveness_marked : 1; Vector _mapped_fonts; Vector _mapped_font_names; Metrics(const Metrics &); // does not exist Metrics &operator=(const Metrics &); // does not exist inline void assign_emap(Glyph, Code); Code hard_encoding(Glyph, Code) const; bool next_encoding(Vector &codes, const Vector &glyphs) const; Ligature *ligature_obj(Code, Code); Kern *kern_obj(Code, Code); inline void new_ligature(Code, Code, Code); inline void repoint_ligature(Code, Ligature *, Code); friend bool operator<(const Ligature3 &, const Ligature3 &); void all_ligatures(Vector &) const; void mark_liveness(int size, const Vector * = 0); void reencode(const Vector &); class ChangedContext; void apply_ligature(const Vector &, const Substitution *, int lookup); void apply_single(Code cin, const Substitution *s, int lookup, ChangedContext &ctx, const GlyphFilter &glyph_filter, const Vector &glyph_names); void apply_simple_context_ligature(const Vector &codes, const Substitution *s, int lookup, ChangedContext &ctx, const GlyphFilter &glyph_filter, const Vector &glyph_names); void apply_alternates_single(Code cin, const Substitution *s, int lookup, const GlyphFilter &glyph_filter, const Vector &glyph_names); void apply_alternates_ligature(const Vector &codes, const Substitution *s, int lookup, const GlyphFilter &glyph_filter, const Vector &glyph_names); void unparse(const Char *) const; }; inline bool Metrics::valid_code(Code code) const { return code >= 0 && code < _encoding.size(); } inline bool Metrics::nonvirtual_code(Code code) const { return code >= 0 && code < _encoding.size() && !_encoding[code].virtual_char; } inline Metrics::Glyph Metrics::glyph(Code code) const { if (code < 0 || code >= _encoding.size()) return 0; else return _encoding[code].glyph; } inline uint32_t Metrics::unicode(Code code) const { if (code < 0 || code >= _encoding.size()) return 0; else return _encoding[code].unicode; } inline Metrics::Glyph Metrics::base_glyph(Code code) const { if (code < 0 || code >= _encoding.size() || _encoding[code].base_code < 0) return 0; else return _encoding[code].glyph; } inline Metrics::Code Metrics::base_code(Code code) const { if (code < 0 || code >= _encoding.size()) return 0; else return _encoding[code].base_code; } inline Metrics::Code Metrics::encoding(Glyph g, Code after) const { Code c; if (g >= 0 && g < _emap.size() && (c = _emap.at_u(g)) >= -1) return c < 0 || c >= after ? c : -1; else return hard_encoding(g, after); } inline void Metrics::assign_emap(Glyph g, Code code) { if (g >= _emap.size()) _emap.resize(g + 1, -1); _emap[g] = (_emap[g] == -1 || _emap[g] == code ? code : -2); } inline const char * Metrics::code_str(Code code) const { return code_name(code).c_str(); } inline bool Metrics::Char::base_glyph() const { return glyph == VIRTUAL_GLYPH ? flags & BASE_REP : glyph != 0; } inline bool Metrics::was_base_glyph(Code code) const { if (code < 0 || code >= _encoding.size()) return 0; else return _encoding[code].base_glyph(); } #endif lcdf-typetools-2.108/otftotfm/uniprop.hh0000644000175000017500000000207513423375330015303 00000000000000#ifndef OTFTOTFM_UNIPROP_HH #define OTFTOTFM_UNIPROP_HH #include class UnicodeProperty { public: enum { P_C = 000, P_Cn = 000, P_Co = 001, P_Cs = 002, P_Cf = 003, P_Cc = 004, P_Z = 010, P_Zs = 010, P_Zl = 011, P_Zp = 012, P_M = 020, P_Mn = 020, P_Mc = 021, P_Me = 022, P_L = 030, P_Lo = 030, P_Lu = 031, P_Ll = 032, P_Lt = 033, P_Lm = 034, P_N = 040, P_No = 040, P_Nd = 041, P_Nl = 042, P_P = 050, P_Po = 050, P_Pc = 051, P_Pd = 052, P_Ps = 053, P_Pe = 054, P_Pi = 055, P_Pf = 056, P_S = 060, P_So = 060, P_Sm = 061, P_Sc = 062, P_Sk = 063, P_TMASK = 0370, P_MAX = 0377 }; static int property(uint32_t uni); static const char* property_name(int p); static bool parse_property(const String&, int& prop, int& prop_mask); private: enum { P_Lul = 070 }; static const unsigned char property_pages[]; static const unsigned int property_offsets[]; static const int nproperty_offsets; static inline const unsigned int* find_offset(uint32_t uni); }; #endif lcdf-typetools-2.108/otftotfm/setting.hh0000644000175000017500000000075513423375330015267 00000000000000#ifndef OTFTOTFM_SETTING_HH #define OTFTOTFM_SETTING_HH #include struct Setting { enum { NONE, FONT, SHOW, KERN, KERNX, MOVE, RULE, PUSH, POP, SPECIAL, DEAD }; int op; int x; int y; String s; Setting(int op_in, int x_in = 0, int y_in = 0) : op(op_in), x(x_in), y(y_in) { } Setting(int op_in, const String &s_in) : op(op_in), s(s_in) { } bool valid_op() const { return op >= FONT && op <= SPECIAL; } }; #endif lcdf-typetools-2.108/otftotfm/Makefile.in0000644000175000017500000005715413423376574015356 00000000000000# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : bin_PROGRAMS = otftotfm$(EXEEXT) @have_kpathsea_TRUE@am__append_1 = kpseinterface.c kpseinterface.h @have_kpathsea_TRUE@am__append_2 = $(KPATHSEA_INCLUDES) @have_kpathsea_TRUE@am__append_3 = $(KPATHSEA_LIBS) @have_kpathsea_TRUE@am__append_4 = $(KPATHSEA_DEPEND) subdir = otftotfm ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/lcdf-typetools.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/autoconf.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" PROGRAMS = $(bin_PROGRAMS) am__otftotfm_SOURCES_DIST = automatic.cc automatic.hh dvipsencoding.cc \ dvipsencoding.hh glyphfilter.cc glyphfilter.hh metrics.cc \ metrics.hh otftotfm.cc otftotfm.hh secondary.cc secondary.hh \ setting.hh uniprop.cc uniprop.hh util.cc util.hh \ kpseinterface.c kpseinterface.h @have_kpathsea_TRUE@am__objects_1 = kpseinterface.$(OBJEXT) am_otftotfm_OBJECTS = automatic.$(OBJEXT) dvipsencoding.$(OBJEXT) \ glyphfilter.$(OBJEXT) metrics.$(OBJEXT) otftotfm.$(OBJEXT) \ secondary.$(OBJEXT) uniprop.$(OBJEXT) util.$(OBJEXT) \ $(am__objects_1) otftotfm_OBJECTS = $(am_otftotfm_OBJECTS) am__DEPENDENCIES_1 = @have_kpathsea_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(otftotfm_SOURCES) $(EXTRA_otftotfm_SOURCES) DIST_SOURCES = $(am__otftotfm_SOURCES_DIST) $(EXTRA_otftotfm_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KPATHSEA_DEPEND = @KPATHSEA_DEPEND@ KPATHSEA_INCLUDES = @KPATHSEA_INCLUDES@ KPATHSEA_LIBS = @KPATHSEA_LIBS@ KPATHSEA_RULE = @KPATHSEA_RULE@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SELECTED_SUBDIRS = @SELECTED_SUBDIRS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TEMPLATE_OBJS = @TEMPLATE_OBJS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ encdir = @encdir@ exec_prefix = @exec_prefix@ glyphlistdir = @glyphlistdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign man_MANS = otftotfm.1 otftotfm_SOURCES = automatic.cc automatic.hh dvipsencoding.cc \ dvipsencoding.hh glyphfilter.cc glyphfilter.hh metrics.cc \ metrics.hh otftotfm.cc otftotfm.hh secondary.cc secondary.hh \ setting.hh uniprop.cc uniprop.hh util.cc util.hh \ $(am__append_1) EXTRA_otftotfm_SOURCES = kpseinterface.c kpseinterface.h otftotfm_LDADD = ../libefont/libefont.a ../liblcdf/liblcdf.a \ $(am__append_3) otftotfm_DEPENDENCIES = ../libefont/libefont.a ../liblcdf/liblcdf.a \ $(am__append_4) AM_CPPFLAGS = -I$(srcdir)/../include $(am__append_2) CLEANFILES = @TEMPLATE_OBJS@ EXTRA_DIST = otftotfm.1 all: all-am .SUFFIXES: .SUFFIXES: .c .cc .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign otftotfm/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign otftotfm/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) otftotfm$(EXEEXT): $(otftotfm_OBJECTS) $(otftotfm_DEPENDENCIES) $(EXTRA_otftotfm_DEPENDENCIES) @rm -f otftotfm$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(otftotfm_OBJECTS) $(otftotfm_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/automatic.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvipsencoding.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glyphfilter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kpseinterface.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/metrics.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/otftotfm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/secondary.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uniprop.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-man uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-binPROGRAMS install-data install-data-am \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-man1 install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-binPROGRAMS uninstall-man uninstall-man1 .PRECIOUS: Makefile @KPATHSEA_RULE@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lcdf-typetools-2.108/otftotfm/metrics.cc0000644000175000017500000014677113423375330015257 00000000000000/* metrics.{cc,hh} -- an encoding during and after OpenType features * * Copyright (c) 2003-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include "metrics.hh" #include "dvipsencoding.hh" #include "util.hh" #include "glyphfilter.hh" #include #include #include #include Metrics::Metrics(const Efont::CharstringProgram *font, int nglyphs) : _boundary_glyph(nglyphs), _emptyslot_glyph(nglyphs + 1), _design_units(1000), _units_per_em(font->units_per_em()), _liveness_marked(false) { _encoding.assign(256, Char()); add_mapped_font(font, String()); } Metrics::~Metrics() { for (Char *c = _encoding.begin(); c != _encoding.end(); c++) delete c->virtual_char; } int Metrics::add_mapped_font(const Efont::CharstringProgram *font, const String &name) { _mapped_fonts.push_back(font); _mapped_font_names.push_back(name); return _mapped_fonts.size() - 1; } void Metrics::check() const { // check invariants // 1. all 'ligatures' entries refer to valid characters // 2. all 'ligatures' entries with 'in1 == c' are in '_encoding[c].ligs' // 3. 'virtual_char' SHOW operations point to valid non-virtual chars for (int code = 0; code < _encoding.size(); code++) { const Char *ch = &_encoding[code]; assert((ch->virtual_char != 0) == (ch->glyph == VIRTUAL_GLYPH)); for (const Ligature *l = ch->ligatures.begin(); l != ch->ligatures.end(); l++) assert(valid_code(l->in2) && valid_code(l->out)); for (const Kern *k = ch->kerns.begin(); k != ch->kerns.end(); k++) assert(valid_code(k->in2)); if (const VirtualChar *vc = ch->virtual_char) { assert(vc->name); int font_number = 0; for (const Setting *s = vc->setting.begin(); s != vc->setting.end(); s++) { assert(s->valid_op()); if (s->op == Setting::SHOW && font_number == 0) assert(nonvirtual_code(s->x)); else if (s->op == Setting::FONT) font_number = s->x; } } assert(ch->built_in1 < 0 || valid_code(ch->built_in1)); assert(ch->built_in2 < 0 || valid_code(ch->built_in2)); assert((ch->built_in1 >= 0) == (ch->built_in2 >= 0)); assert(ch->base_code < 0 || valid_code(ch->base_code)); if (valid_code(ch->base_code)) { const Char *ch2 = &_encoding[ch->base_code]; assert((!ch->virtual_char && ch->glyph) || (!ch2->virtual_char && ch2->glyph)); } if (ch->flag(Char::CONTEXT_ONLY)) assert(ch->virtual_char && ch->built_in1 >= 0 && ch->built_in2 >= 0); if (ch->flag(Char::CONTEXT_ONLY)) assert(ch->flag(Char::LIVE)); } } PermString Metrics::code_name(Code code) const { if (code < 0 || code >= _encoding.size()) return permprintf("", code); else { const Char &ch = _encoding[code]; if (ch.virtual_char) return ch.virtual_char->name; else if (ch.glyph == _boundary_glyph) return ""; else if (ch.glyph == _emptyslot_glyph) return ""; else if (ch.glyph >= 0 && ch.glyph < _mapped_fonts[0]->nglyphs()) return _mapped_fonts[0]->glyph_name(ch.glyph); else return permprintf("", ch.glyph); } } /*****************************************************************************/ /* encoding */ Metrics::Code Metrics::unicode_encoding(uint32_t uni) const { for (const Char *ch = _encoding.begin(); ch < _encoding.end(); ch++) if (ch->unicode == uni) return ch - _encoding.begin(); return -1; } Metrics::Code Metrics::hard_encoding(Glyph g, Code after) const { if (g < 0) return -1; int answer = -1, n = 0; for (int i = _encoding.size() - 1; i >= after; i--) if (_encoding[i].glyph == g) answer = i, n++; if (n < 2 && after == 0) { if (g >= _emap.size()) _emap.resize(g + 1, -2); _emap[g] = answer; } return answer; } Metrics::Code Metrics::force_encoding(Glyph g, int lookup_source) { assert(g >= 0); int e = encoding(g, 0); if (e >= 0) return e; else { Char ch; ch.glyph = g; ch.base_code = _encoding.size(); ch.lookup_source = lookup_source; _encoding.push_back(ch); assign_emap(g, ch.base_code); return ch.base_code; } } void Metrics::encode(Code code, uint32_t uni, Glyph g) { assert(code >= 0 && g >= 0 && g != VIRTUAL_GLYPH); if (code >= _encoding.size()) _encoding.resize(code + 1, Char()); _encoding[code].unicode = uni; _encoding[code].glyph = g; if (g > 0) _encoding[code].base_code = code; assert(!_encoding[code].virtual_char); assign_emap(g, code); } void Metrics::encode_virtual(Code code, PermString name, uint32_t uni, const Vector &v, bool base_char) { assert(code >= 0 && v.size() > 0); if (code >= _encoding.size()) _encoding.resize(code + 1, Char()); _encoding[code].unicode = uni; _encoding[code].glyph = VIRTUAL_GLYPH; if (base_char) _encoding[code].flags |= Char::BASE_REP; assert(!_encoding[code].virtual_char); VirtualChar *vc = _encoding[code].virtual_char = new VirtualChar; vc->name = name; vc->setting = v; int font_number = 0; for (Setting *s = vc->setting.begin(); s != vc->setting.end(); s++) { assert(s->valid_op() && (s->op != Setting::SHOW || font_number != 0 || nonvirtual_code(s->x))); if (s->op == Setting::FONT) font_number = s->x; } } void Metrics::apply_base_encoding(const String &font_name, const DvipsEncoding &dvipsenc, const Vector &mapping) { int font_number = -1; for (Char *c = _encoding.begin(); c != _encoding.end(); c++) if (c->glyph > 0 && !c->virtual_char && c->glyph < mapping.size() && mapping[c->glyph] >= 0) { if (font_number < 0) font_number = add_mapped_font(mapped_font(0), font_name); VirtualChar *vc = c->virtual_char = new VirtualChar; vc->name = dvipsenc.encoding(mapping[c->glyph]); vc->setting.push_back(Setting(Setting::FONT, font_number)); vc->setting.push_back(Setting(Setting::SHOW, mapping[c->glyph], c->glyph)); c->glyph = VIRTUAL_GLYPH; c->base_code = -1; c->flags = (c->flags & ~Char::BASE_LIVE) | Char::BASE_REP; } } void Metrics::add_altselector_code(Code code, int altselector_type) { for (Kern *k = _altselectors.begin(); k != _altselectors.end(); k++) if (k->in2 == code) { k->kern = altselector_type; return; } _altselectors.push_back(Kern(code, altselector_type)); } bool Metrics::base_glyphs(Vector &v, int size) const { bool any = false; v.assign(_encoding.size(), 0); for (const Char *ch = _encoding.begin(); ch != _encoding.end(); ch++) if (ch->base_code >= 0 && ch->base_code < size) { v[ch->base_code] = ch->glyph; any = true; } return any; } /*****************************************************************************/ /* Char methods */ void Metrics::Char::clear() { glyph = 0; base_code = -1; unicode = 0; ligatures.clear(); kerns.clear(); delete virtual_char; virtual_char = 0; pdx = pdy = adx = 0; built_in1 = built_in2 = -1; lookup_source = -1; flags = 0; } void Metrics::Char::swap(Char &c) { std::swap(glyph, c.glyph); // NB: only a partial switch of base_code!! if (base_code < 0) base_code = c.base_code; c.base_code = -1; std::swap(unicode, c.unicode); ligatures.swap(c.ligatures); kerns.swap(c.kerns); std::swap(virtual_char, c.virtual_char); std::swap(pdx, c.pdx); std::swap(pdy, c.pdy); std::swap(adx, c.adx); std::swap(built_in1, c.built_in1); std::swap(built_in2, c.built_in2); std::swap(lookup_source, c.lookup_source); std::swap(flags, c.flags); } /*****************************************************************************/ /* manipulating ligature lists */ Metrics::Ligature * Metrics::ligature_obj(Code code1, Code code2) { assert(valid_code(code1) && valid_code(code2)); Char &ch = _encoding[code1]; for (Ligature *l = ch.ligatures.begin(); l != ch.ligatures.end(); l++) if (l->in2 == code2) return l; return 0; } inline void Metrics::new_ligature(Code in1, Code in2, Code out) { assert(valid_code(in1) && valid_code(in2) && valid_code(out)); _encoding[in1].ligatures.push_back(Ligature(in2, out)); } inline void Metrics::repoint_ligature(Code, Ligature *l, Code out) { l->out = out; } void Metrics::add_ligature(Code in1, Code in2, Code out) { if (Ligature *l = ligature_obj(in1, in2)) { Char &ch = _encoding[l->out]; if (ch.flags & Char::BUILT) { // move old ligatures to point to the true ligature for (Ligature *ll = ch.ligatures.begin(); ll != ch.ligatures.end(); ll++) add_ligature(out, ll->in2, ll->out); repoint_ligature(in1, l, out); } } else new_ligature(in1, in2, out); } Metrics::Code Metrics::pair_code(Code in1, Code in2, int lookup_source) { if (const Ligature *l = ligature_obj(in1, in2)) { if (lookup_source < 0) _encoding[l->out].flags &= ~Char::INTERMEDIATE; return l->out; } else { Char ch; ch.glyph = VIRTUAL_GLYPH; ch.flags = Char::BUILT | (lookup_source >= 0 ? Char::INTERMEDIATE : 0); VirtualChar *vc = ch.virtual_char = new VirtualChar; vc->name = permprintf("%s__%s", code_str(in1), code_str(in2)); setting(in1, vc->setting, SET_INTERMEDIATE); vc->setting.push_back(Setting(Setting::KERN)); setting(in2, vc->setting, SET_INTERMEDIATE); ch.built_in1 = in1; ch.built_in2 = in2; ch.lookup_source = lookup_source; _encoding.push_back(ch); new_ligature(in1, in2, _encoding.size() - 1); return _encoding.size() - 1; } } void Metrics::remove_ligatures(Code in1, Code in2) { if (in1 == CODE_ALL) { for (in1 = 0; in1 < _encoding.size(); in1++) remove_ligatures(in1, in2); } else { Char &ch = _encoding[in1]; if (in2 == CODE_ALL) ch.ligatures.clear(); else if (Ligature *l = ligature_obj(in1, in2)) { *l = ch.ligatures.back(); ch.ligatures.pop_back(); } } } /*****************************************************************************/ /* manipulating kern lists */ Metrics::Kern * Metrics::kern_obj(Code in1, Code in2) { assert(valid_code(in1) && valid_code(in2)); Char &ch = _encoding[in1]; for (Kern *k = ch.kerns.begin(); k != ch.kerns.end(); k++) if (k->in2 == in2) return k; return 0; } int Metrics::kern(Code in1, Code in2) const { assert(valid_code(in1) && valid_code(in2)); const Char &ch = _encoding[in1]; for (const Kern *k = ch.kerns.begin(); k != ch.kerns.end(); k++) if (k->in2 == in2) return k->kern; return 0; } void Metrics::add_kern(Code in1, Code in2, int kern) { if (Kern *k = kern_obj(in1, in2)) k->kern += kern; else _encoding[in1].kerns.push_back(Kern(in2, kern)); } void Metrics::set_kern(Code in1, Code in2, int kern) { if (in1 == CODE_ALL) { for (in1 = 0; in1 < _encoding.size(); in1++) set_kern(in1, in2, kern); } else { Char &ch = _encoding[in1]; if (in2 == CODE_ALL) { assert(kern == 0); ch.kerns.clear(); } else if (Kern *k = kern_obj(in1, in2)) { if (kern == 0) { *k = ch.kerns.back(); ch.kerns.pop_back(); } else k->kern = kern; } else if (kern != 0) ch.kerns.push_back(Kern(in2, kern)); } } int Metrics::reencode_right_ligkern(Code old_in2, Code new_in2) { int nchanges = 0; for (Char *ch = _encoding.begin(); ch != _encoding.end(); ch++) { for (Ligature *l = ch->ligatures.begin(); l != ch->ligatures.end(); l++) if (l->in2 == old_in2) { if (new_in2 >= 0) l->in2 = new_in2; else { *l = ch->ligatures.back(); ch->ligatures.pop_back(); l--; } nchanges++; } for (Kern *k = ch->kerns.begin(); k != ch->kerns.end(); k++) if (k->in2 == old_in2) { if (new_in2 >= 0) k->in2 = new_in2; else { *k = ch->kerns.back(); ch->kerns.pop_back(); k--; } nchanges++; } // XXX? if (ch->context_setting(-1, old_in2) && new_in2 >= 0 && ch->built_in1 >= 0) ch->built_in2 = new_in2; } return nchanges; } /*****************************************************************************/ /* positioning */ void Metrics::add_single_positioning(Code c, int pdx, int pdy, int adx) { assert(valid_code(c)); Char &ch = _encoding[c]; ch.pdx += pdx; ch.pdy += pdy; ch.adx += adx; } /*****************************************************************************/ /* changed_context structure */ class Metrics::ChangedContext { public: ChangedContext(int ncodes); ~ChangedContext(); typedef Metrics::Code Code; enum Context { CH_NONE = 0, CH_SOME = 1, CH_ALL = 2 }; bool allowed(Code, bool left_context) const; bool pair_allowed(Code, Code) const; bool virgin(Code) const; void disallow(Code); void disallow_pair(Code, Code); private: Vector *> _v; int _initial_ncodes; mutable Vector _all_sentinel; ChangedContext(const ChangedContext &); ChangedContext &operator=(const ChangedContext &); static inline bool bit(const Vector &, Code); inline void ensure_all(Code) const; }; Metrics::ChangedContext::ChangedContext(int ncodes) : _v(ncodes, 0), _initial_ncodes(ncodes), _all_sentinel(((ncodes - 1) >> 5) + 1, 0xFFFFFFFFU) { } Metrics::ChangedContext::~ChangedContext() { for (Vector **v = _v.begin(); v != _v.end(); v++) if (*v != &_all_sentinel) delete *v; } inline void Metrics::ChangedContext::ensure_all(Code c) const { if (c >= 0 && (c >> 5) >= _all_sentinel.size()) _all_sentinel.resize((c >> 5) + 1, 0xFFFFFFFFU); } inline bool Metrics::ChangedContext::bit(const Vector &v, Code c) { if (c < 0 || (c >> 5) >= v.size()) return false; else return (v[c >> 5] & (1 << (c & 0x1F))) != 0; } bool Metrics::ChangedContext::allowed(Code c, bool left_context) const { if (c < 0) return false; else if (c >= _v.size()) return left_context; else return (_v[c] != &_all_sentinel); } bool Metrics::ChangedContext::pair_allowed(Code c1, Code c2) const { ensure_all(c2); if (c1 < 0 || c2 < 0) return false; else if (c1 >= _v.size() || c2 >= _v.size() || !_v[c1]) return true; else return !bit(*_v[c1], c2); } bool Metrics::ChangedContext::virgin(Code c) const { return (c >= 0 && (c >= _v.size() || _v[c] == 0)); } void Metrics::ChangedContext::disallow(Code c) { assert(c >= 0); if (c >= _v.size()) _v.resize(c + 1, 0); if (_v[c] != &_all_sentinel) { delete _v[c]; _v[c] = &_all_sentinel; } } void Metrics::ChangedContext::disallow_pair(Code c1, Code c2) { assert(c1 >= 0 && c2 >= 0); if (c1 >= _v.size()) _v.resize(c1 + 1, 0); if (!_v[c1]) _v[c1] = new Vector; if (_v[c1] != &_all_sentinel) { if ((c2 >> 5) >= _v[c1]->size()) _v[c1]->resize((c2 >> 5) + 1, 0); (*_v[c1])[c2 >> 5] |= 1 << (c2 & 0x1F); } } /*****************************************************************************/ /* applying GSUB substitutions */ void Metrics::apply_single(Code cin, const Substitution *s, int lookup, ChangedContext &ctx, const GlyphFilter &glyph_filter, const Vector &glyph_names) { // check if encoded if (!ctx.allowed(cin, false)) /* not encoded before this substitution began, or completely changed; ingore */ return; // check if substitution of this code allowed if (!glyph_filter.allow_substitution(s->in_glyph(), glyph_names, unicode(cin))) return; // look for an allowed alternate Glyph out = -1; for (int i = 0; out < 0 && i < s->out_nglyphs(); i++) if (glyph_filter.allow_alternate(s->out_glyph(i), glyph_names, unicode(cin))) out = s->out_glyph(i); if (out < 0) // no allowed alternate return; // apply substitution if (ctx.virgin(cin)) { // no one has changed this glyph yet, change it unilaterally assign_emap(s->in_glyph(), -2); assign_emap(out, cin); assert(!_encoding[cin].virtual_char); _encoding[cin].glyph = out; } else { // some contextual substitutions have changed this glyph, add // contextual substitutions for the remaining possibilities Code cout = force_encoding(out, lookup); for (Code right = 0; right < _encoding.size(); right++) if (_encoding[right].visible() && !_encoding[right].flag(Char::BUILT) && ctx.pair_allowed(cin, right)) { Code pair = pair_code(cout, right, lookup); _encoding[cout].flags &= ~Char::INTERMEDIATE; add_ligature(cin, right, pair); } } // no more substitutions for cin ctx.disallow(cin); } void Metrics::apply_ligature(const Vector &in, const Substitution *s, int lookup) { // build up the character pair int cin1 = in[0]; for (const Code *inp = in.begin() + 1; inp < in.end() - 1; inp++) cin1 = pair_code(cin1, *inp, lookup); int cin2 = in.back(); // build up the output character Vector out; s->all_out_glyphs(out); int cout = -1; for (Glyph *outp = out.begin(); outp < out.end(); outp++) { *outp = force_encoding(*outp, lookup); cout = (cout < 0 ? *outp : pair_code(cout, *outp, lookup)); } _encoding[cout].flags &= ~Char::INTERMEDIATE; // check for replacing a fake ligature int old_out = -1; if (Ligature *l = ligature_obj(cin1, cin2)) { if (l->out == cout) // already created this same ligature return; if (_encoding[l->out].flags & Char::BUILT) old_out = l->out; } // make the final ligature add_ligature(cin1, cin2, cout); //fprintf(stderr, "%s : %d/%s %d/%s => %d/%s [was %d/%s]\n", s->unparse().c_str(), cin1, code_str(cin1), cin2, code_str(cin2), cout, code_str(cout), old_out, code_str(old_out)); // if appropriate, swap old ligatures to point to the new result if (old_out >= 0) for (Char *ch = _encoding.begin(); ch != _encoding.end(); ch++) for (Ligature *l = ch->ligatures.begin(); l != ch->ligatures.end(); l++) if (l->out == old_out) repoint_ligature(ch - _encoding.begin(), l, cout); } void Metrics::apply_simple_context_ligature(const Vector &codes, const Substitution *s, int lookup, ChangedContext &ctx, const GlyphFilter &glyph_filter, const Vector& glyph_names) { int nleft = s->left_nglyphs(), nin = s->in_nglyphs(); assert(codes.size() >= 2); // check if context allows substitutions for (int i = 0; i < codes.size(); ++i) { if (!ctx.allowed(codes[i], i < nleft) || !glyph_filter.allow_substitution(s->in_glyph(i), glyph_names, unicode(codes[i]))) return; } // check if any part of the combination has already changed int ncheck = nleft + (nin > 2 ? 2 : nin); if (ncheck == codes.size()) --ncheck; for (const Code *inp = codes.begin(); inp < codes.begin() + ncheck; ++inp) if (!ctx.pair_allowed(inp[0], inp[1])) return; // mark this combination as changed if appropriate if (codes.size() == 2 && nin == 1) ctx.disallow_pair(codes[0], codes[1]); // actually apply ligature apply_ligature(codes, s, lookup); } bool Metrics::next_encoding(Vector &codes, const Vector &glyphs) const { if (!codes.size()) { codes.assign(glyphs.size(), 0); for (int i = 0; i < glyphs.size(); ++i) if ((codes[i] = encoding(glyphs[i], 0)) < 0) return false; return true; } else { for (int i = 0; i < glyphs.size(); ++i) if ((codes[i] = encoding(glyphs[i], codes[i] + 1)) >= 0) return true; else codes[i] = encoding(glyphs[i], 0); return false; } } int Metrics::apply(const Vector& sv, bool allow_single, int lookup, const GlyphFilter& glyph_filter, const Vector& glyph_names) { Vector glyphs; Vector codes; // keep track of what substitutions we have performed ChangedContext ctx(_encoding.size()); // loop over substitutions int failures = 0; for (const Substitution *s = sv.begin(); s != sv.end(); s++) { bool is_single = s->is_single() || s->is_alternate(); bool is_apply_single = is_single && allow_single; bool is_apply_simple_context_ligature = !is_single && !s->is_multiple() && s->is_simple_context(); if (is_apply_single || is_apply_simple_context_ligature) { s->all_in_glyphs(glyphs); for (codes.clear(); next_encoding(codes, glyphs); ) { if (is_apply_single) apply_single(codes[0], s, lookup, ctx, glyph_filter, glyph_names); else apply_simple_context_ligature(codes, s, lookup, ctx, glyph_filter, glyph_names); } } else failures++; } return sv.size() - failures; } void Metrics::apply_alternates_single(Code cin, const Substitution *s, int lookup, const GlyphFilter &glyph_filter, const Vector &glyph_names) { for (const Kern *as = _altselectors.begin(); as != _altselectors.end(); as++) if (as->kern == 0) { Code last = cin; uint32_t u = unicode(cin); for (int i = 0; i < s->out_nglyphs(); i++) if (glyph_filter.allow_alternate(s->out_glyph(i), glyph_names, u)) { Code out = force_encoding(s->out_glyph(i), lookup); add_ligature(last, as->in2, out); last = out; } } else if (as->kern <= s->out_nglyphs()) { Code out = force_encoding(s->out_glyph(as->kern - 1), lookup); add_ligature(cin, as->in2, out); } } void Metrics::apply_alternates_ligature(const Vector &codes, const Substitution *s, int lookup, const GlyphFilter &glyph_filter, const Vector &glyph_names) { // check whether the output character is allowed if (!glyph_filter.allow_alternate(s->out_glyph(), glyph_names, 0)) return; // find alternate selector and apply ligature if appropriate for (const Kern *as = _altselectors.begin(); as != _altselectors.end(); as++) if (as->kern == 0) { Vector lig(codes); lig.insert(lig.begin() + 1, as->in2); apply_ligature(lig, s, lookup); } } void Metrics::apply_alternates(const Vector& sv, int lookup, const GlyphFilter& glyph_filter, const Vector& glyph_names) { Vector glyphs; Vector codes; for (const Substitution *s = sv.begin(); s != sv.end(); s++) { bool is_single = s->is_single() || s->is_alternate(); if (is_single || s->is_ligature()) { s->all_in_glyphs(glyphs); for (codes.clear(); next_encoding(codes, glyphs); ) { if (is_single) apply_alternates_single(codes[0], s, lookup, glyph_filter, glyph_names); else apply_alternates_ligature(codes, s, lookup, glyph_filter, glyph_names); } } } } /*****************************************************************************/ /* applying GPOS positionings */ static bool // returns old value assign_bitvec(int*& bitvec, int e, int n) { if (e >= 0 && e < n) { if (!bitvec) { bitvec = new int[((n - 1) >> 5) + 1]; memset(bitvec, 0, sizeof(int) * (((n - 1) >> 5) + 1)); } bool result = (bitvec[e >> 5] & (1 << (e & 0x1F))) != 0; bitvec[e >> 5] |= (1 << (e & 0x1F)); return result; } else return false; } int Metrics::apply(const Vector& pv) { // keep track of what substitutions we have performed int *single_changed = 0; Vector pair_changed(_encoding.size(), 0); Vector glyphs; Vector codes; // loop over substitutions int success = 0; for (const Positioning *p = pv.begin(); p != pv.end(); p++) { bool is_single = p->is_single(); if (is_single || p->is_pairkern()) { p->all_in_glyphs(glyphs); for (codes.clear(); next_encoding(codes, glyphs); ) if (is_single) { if (!assign_bitvec(single_changed, codes[0], _encoding.size())) { _encoding[codes[0]].pdx += p->left().pdx; _encoding[codes[0]].pdy += p->left().pdy; _encoding[codes[0]].adx += p->left().adx; } } else { if (!assign_bitvec(pair_changed[codes[0]], codes[1], _encoding.size())) add_kern(codes[0], codes[1], p->left().adx); } success++; } } delete[] single_changed; for (int i = 0; i < pair_changed.size(); i++) delete[] pair_changed[i]; return success; } /*****************************************************************************/ /* liveness marking, Ligature3s */ String Metrics::Ligature3::unparse(const Metrics& m) const { StringAccum sa; sa << '[' << m.code_name(in1) << ' ' << m.code_name(in2) << " -> " << m.code_name(out) << ']'; return sa.take_string(); } inline bool operator<(const Metrics::Ligature3 &l1, const Metrics::Ligature3 &l2) { // topological < : is l1's output one of l2's inputs? if (l1.out == l2.in1 || l1.out == l2.in2) return true; else return l1.in1 < l2.in1 || (l1.in1 == l2.in1 && (l1.in2 < l2.in2 || (l1.in2 == l2.in2 && l1.out < l2.out))); } void Metrics::all_ligatures(Vector &all_ligs) const { /* Develop a topologically-sorted ligature list. */ all_ligs.clear(); for (Code code = 0; code < _encoding.size(); code++) for (const Ligature *l = _encoding[code].ligatures.begin(); l != _encoding[code].ligatures.end(); l++) all_ligs.push_back(Ligature3(code, l->in2, l->out)); std::sort(all_ligs.begin(), all_ligs.end()); } void Metrics::mark_liveness(int size, const Vector *all_ligs) { _liveness_marked = true; bool changed; // make sure we have ligatures Vector my_ligs; if (!all_ligs) { all_ligatures(my_ligs); all_ligs = &my_ligs; } /* Characters below 'size' are in both virtual and base encodings. */ for (Char *ch = _encoding.begin(); ch < _encoding.begin() + size; ch++) if (ch->visible()) ch->flags |= Char::LIVE | (ch->virtual_char ? 0 : Char::BASE_LIVE); /* Characters reachable from live chars by live ligatures are live. */ redo_live_reachable: for (const Ligature3 *l = all_ligs->begin(); l != all_ligs->end(); l++) if (_encoding[l->in1].flag(Char::LIVE) && _encoding[l->in2].flag(Char::LIVE)) { Char &ch = _encoding[l->out]; if (!ch.flag(Char::LIVE)) ch.flags |= Char::LIVE | Char::CONTEXT_ONLY | (ch.virtual_char ? 0 : Char::BASE_LIVE); if (ch.flag(Char::CONTEXT_ONLY) && !ch.context_setting(l->in1, l->in2)) ch.flags &= ~Char::CONTEXT_ONLY; } /* Characters reachable from context-only ligatures are live. */ changed = false; for (Char *ch = _encoding.begin(); ch != _encoding.end(); ch++) if (ch->flag(Char::CONTEXT_ONLY)) { Char &ch1 = _encoding[ch->built_in1]; Char &ch2 = _encoding[ch->built_in2]; if (!ch1.flag(Char::LIVE) || !ch2.flag(Char::LIVE)) { ch1.flags |= Char::LIVE; ch2.flags |= Char::LIVE; changed = true; } } if (changed) goto redo_live_reachable; /* Characters reachable from live settings are base-live. */ for (Char *ch = _encoding.begin(); ch != _encoding.end(); ch++) if (ch->flag(Char::LIVE)) if (VirtualChar *vc = ch->virtual_char) { int font_number = 0; for (Setting *s = vc->setting.begin(); s != vc->setting.end(); s++) if (s->op == Setting::SHOW && font_number == 0 && _encoding[s->x].base_code >= 0) _encoding[s->x].flags |= Char::BASE_LIVE; else if (s->op == Setting::FONT) font_number = s->x; } } void Metrics::reencode(const Vector &reencoding) { for (Char *ch = _encoding.begin(); ch != _encoding.end(); ch++) { for (Ligature *l = ch->ligatures.begin(); l != ch->ligatures.end(); l++) { l->in2 = reencoding[l->in2]; l->out = reencoding[l->out]; } for (Kern *k = ch->kerns.begin(); k != ch->kerns.end(); k++) k->in2 = reencoding[k->in2]; if (VirtualChar *vc = ch->virtual_char) { int font_number = 0; for (Setting *s = vc->setting.begin(); s != vc->setting.end(); s++) if (s->op == Setting::SHOW && font_number == 0) s->x = reencoding[s->x]; else if (s->op == Setting::FONT) font_number = s->x; } if (ch->built_in1 >= 0) { ch->built_in1 = reencoding[ch->built_in1]; ch->built_in2 = reencoding[ch->built_in2]; } if (ch->base_code >= 0) ch->base_code = reencoding[ch->base_code]; } _emap.clear(); } /*****************************************************************************/ /* shrinking the encoding */ bool Metrics::Char::context_setting(Code in1, Code in2) const { // return true iff this character could represent the context setting of // 'in1' and 'in2' if (!virtual_char || ligatures.size()) return false; else return (in1 == built_in1 || in2 == built_in2); } void Metrics::cut_encoding(int size) { /* Function makes it so that characters below 'size' do not point to characters above 'size', except for context ligatures. */ /* Change "emptyslot"s to ".notdef"s. */ for (Char *ch = _encoding.begin(); ch != _encoding.end(); ch++) if (ch->glyph == emptyslot_glyph()) { ch->glyph = 0; ch->base_code = -1; // 21.Feb.2007: Character isn't live any more. ch->flags &= ~(Char::BASE_LIVE | Char::LIVE); } /* Maybe we don't need to do anything else. */ if (_encoding.size() <= size) { _encoding.resize(size, Char()); return; } /* Need liveness markings. */ if (!_liveness_marked) mark_liveness(size); /* Characters below 'size' are 'good'. Characters above 'size' are not 'good'. */ Vector good(_encoding.size(), 1); for (Code c = size; c < _encoding.size(); c++) good[c] = 0; /* Characters encoded via base_code are 'good', though. */ for (Char *ch = _encoding.begin(); ch < _encoding.begin() + size; ch++) if (ch->base_code >= size) good[ch->base_code] = 1; /* Some fake characters might point beyond 'size'; remove them too. No need for a multipass algorithm since virtual chars never point to virtual chars. */ for (Code c = 0; c < _encoding.size(); c++) { if (VirtualChar *vc = _encoding[c].virtual_char) { int font_number = 0; for (Setting *s = vc->setting.begin(); s != vc->setting.end(); s++) if (s->op == Setting::SHOW && font_number == 0 && !good[s->x]) { _encoding[c].clear(); goto bad_virtual_char; } else if (s->op == Setting::FONT) font_number = s->x; } if (c < size) good[c] = 1; bad_virtual_char: ; } /* Certainly none of the later ligatures or kerns will be meaningful. */ for (Code c = size; c < _encoding.size(); c++) { _encoding[c].ligatures.clear(); _encoding[c].kerns.clear(); } /* Remove ligatures and kerns that point beyond 'size', except for valid context ligatures. Also remove ligatures that have non-live components. */ /* 30.May.2005 -- Kerns might point involve a too-high character; kill them. */ for (Code c = 0; c < size; c++) { Char &ch = _encoding[c]; for (Ligature *l = ch.ligatures.begin(); l != ch.ligatures.end(); l++) if (!good[l->in2] || l->in2 >= size || (!good[l->out] && !_encoding[l->out].context_setting(c, l->in2))) { *l = ch.ligatures.back(); ch.ligatures.pop_back(); l--; } for (Kern *k = ch.kerns.begin(); k != ch.kerns.end(); k++) if (!good[k->in2] || k->in2 >= size) { *k = ch.kerns.back(); ch.kerns.pop_back(); k--; } } /* We are done! */ } namespace { // preference-sorting extra characters enum { CONVENTIONAL_F_LIGATURE_SCORE = 4, CONVENTIONAL_F_F_LIGATURE_SCORE = 5, BASIC_LATIN_LOWER_SCORE = 3, BASIC_LATIN_UPPER_SCORE = 4, BASIC_LATIN_OTHER_SCORE = 5, LATIN1_SUPPLEMENT_SCORE = 6, LOW_16_SCORE = 7, OTHER_SCORE = 8, NOCHAR_SCORE = 100000, CONTEXT_PENALTY = 4 }; static int unicode_score(uint32_t u) { if (u == 0) return NOCHAR_SCORE; else if (u >= 'a' && u <= 'z') return BASIC_LATIN_LOWER_SCORE; else if (u >= 'A' && u <= 'Z') return BASIC_LATIN_UPPER_SCORE; else if (u < 0x0080) return BASIC_LATIN_OTHER_SCORE; else if (u < 0x0100) return LATIN1_SUPPLEMENT_SCORE; else if (u < 0x8000) return LOW_16_SCORE; else return OTHER_SCORE; } struct Slot { Metrics::Code old_code; Metrics::Code new_code; Metrics::Glyph glyph; int score; int lookup_source; }; inline bool operator<(const Slot &a, const Slot &b) { // note: will give real glyphs priority over virtual ones at a given // priority // 6.Jul.2014 -- Make sure you include an old_code comparison; this // is required to ensure that a ligature's inputs (which have smaller // old_codes) are included whenever its outputs are included. if (a.lookup_source != b.lookup_source) return a.lookup_source < b.lookup_source; if (a.score != b.score) return a.score < b.score; if (a.glyph != b.glyph) return a.glyph < b.glyph; return a.old_code < b.old_code; } } void Metrics::shrink_encoding(int size, const DvipsEncoding &dvipsenc, ErrorHandler *errh) { /* Move characters around. */ /* Maybe we don't need to do anything. */ if (_encoding.size() <= size) { cut_encoding(size); return; } /* Need a list of all ligatures.. */ Vector all_ligs; all_ligatures(all_ligs); /* Need liveness markings. */ if (!_liveness_marked) mark_liveness(size, &all_ligs); /* Score characters by importance. Importance relates first to Unicode values, and then recursively to the importances of characters that form a ligature. */ /* Create an initial set of scores, based on Unicode values. */ Vector scores(_encoding.size(), NOCHAR_SCORE); for (int i = 0; i < _encoding.size(); i++) if (_encoding[i].unicode) scores[i] = unicode_score(_encoding[i].unicode); /* Prefer conventional f-ligatures. */ bool has_ff = false; for (Ligature3* l = all_ligs.begin(); l != all_ligs.end(); ++l) if (_encoding[l->in1].unicode == 'f' && (_encoding[l->in2].unicode == 'f' || _encoding[l->in2].unicode == 'i' || _encoding[l->in2].unicode == 'l')) { if (scores[l->out] > CONVENTIONAL_F_LIGATURE_SCORE) scores[l->out] = CONVENTIONAL_F_LIGATURE_SCORE; if (_encoding[l->in2].unicode == 'f') { _encoding[l->out].flags |= Char::IS_FF; has_ff = true; } } if (has_ff) for (Ligature3* l = all_ligs.begin(); l != all_ligs.end(); ++l) if (_encoding[l->in1].flag(Char::IS_FF) && (_encoding[l->in2].unicode == 'i' || _encoding[l->in2].unicode == 'l') && scores[l->out] > CONVENTIONAL_F_F_LIGATURE_SCORE) scores[l->out] = CONVENTIONAL_F_F_LIGATURE_SCORE; /* Repeat these steps until you reach a stable set of scores: Score ligatures (ligscore = SUM[char scores]), then score characters touched only by fakes. */ bool changed = true; while (changed) { changed = false; for (Ligature3 *l = all_ligs.begin(); l != all_ligs.end(); l++) { int score = scores[l->in1] + scores[l->in2]; if (scores[l->out] > score) scores[l->out] = score, changed = true; } for (Code c = 0; c < _encoding.size(); c++) if (VirtualChar *vc = _encoding[c].virtual_char) { /* Make sure that if this virtual character appears, its parts will also appear, by scoring the parts less */ int score = scores[c] - 1, font_number = 0; for (Setting *s = vc->setting.begin(); s != vc->setting.end(); s++) if (s->op == Setting::SHOW && font_number == 0 && score < scores[s->x]) scores[s->x] = score, changed = true; else if (s->op == Setting::FONT) font_number = s->x; } } /* Rescore intermediates to not be better off than their endpoints. */ /* XXX multiple layers of intermediate? */ for (Code c = 0; c < _encoding.size(); c++) { Char &ch = _encoding[c]; if (ch.flag(Char::INTERMEDIATE)) for (Ligature *l = ch.ligatures.begin(); l != ch.ligatures.end(); l++) if (scores[c] < scores[l->out] && !_encoding[l->out].context_setting(c, l->in2)) scores[c] = scores[l->out]; } /* Collect characters that want to be reassigned. */ Vector slots; for (Code c = size; c < _encoding.size(); c++) if (scores[c] < NOCHAR_SCORE && !(_encoding[c].flags & Char::CONTEXT_ONLY) && (_encoding[c].flags & (Char::LIVE | Char::BASE_LIVE))) { Slot slot = { c, -1, _encoding[c].glyph, scores[c], _encoding[c].lookup_source }; slots.push_back(slot); } // Sort them by score, then by glyph. std::sort(slots.begin(), slots.end()); /* Prefer their old slots, if available. */ for (Slot *slot = slots.begin(); slot < slots.end(); slot++) if (PermString g = code_name(slot->old_code)) { int c = dvipsenc.encoding_of(g); if (c >= 0 && _encoding[c].glyph == 0) { _encoding[c].swap(_encoding[slot->old_code]); slot->new_code = c; } } /* List empty slots in two phases: Those not encoded by the input encoding, then those encoded by the input encoding (but that character wasn't available). */ Vector empty_codes; for (int want_encoded = 0; want_encoded < 2; want_encoded++) for (Code c = 0; c < size; c++) if (_encoding[c].base_code < 0 && dvipsenc.encoded(c) == (bool) want_encoded) empty_codes.push_back(c); /* Then, assign codes to the unencoded characters. */ int nunencoded = 0; for (Slot *slot = slots.begin(); slot != slots.end(); slot++) { if (slot->new_code >= 0) continue; int needs = (_encoding[slot->old_code].visible_base() ? 1 : 0) + (_encoding[slot->old_code].flag(Char::LIVE) ? 2 : 0); assert(needs > 0); Code dest = -1; for (Code *h = empty_codes.begin(); h < empty_codes.end() && dest < 0; h++) { int haves = (_encoding[*h].base_code < 0 ? 1 : 0) + (!_encoding[*h].visible() ? 2 : 0); if ((needs & haves) == needs) dest = *h; } if (dest >= 0) { if (needs & 2) { assert(!_encoding[dest].visible()); _encoding[dest].swap(_encoding[slot->old_code]); slot->new_code = dest; } else { _encoding[slot->old_code].base_code = dest; slot->new_code = slot->old_code; } if (needs & 1) { assert(_encoding[dest].base_code < 0 || _encoding[dest].base_code == slot->old_code); _encoding[dest].base_code = slot->old_code; } } else nunencoded++; } /* Complain if some characters can't fit. */ if (nunencoded) { // collect names of unencoded glyphs Vector unencoded; for (Slot *slot = slots.begin(); slot != slots.end(); slot++) if (slot->new_code < 0) unencoded.push_back(code_name(slot->old_code)); std::sort(unencoded.begin(), unencoded.end()); StringAccum sa; for (const String* a = unencoded.begin(); a < unencoded.end(); a++) sa << *a << ' '; sa.pop_back(); sa.append_break_lines(sa.take_string(), 68, " "); sa.pop_back(); errh->lwarning(" ", (unencoded.size() == 1 ? "not enough room in encoding, ignoring %d glyph" : "not enough room in encoding, ignoring %d glyphs"), unencoded.size()); errh->lmessage(" ", "(\ The font uses more glyphs than the encoding has available slots,\n\ so these glyphs have been left out:\n%s\n\ To select specific glyphs, add them to the input encoding.)", sa.c_str()); } /* Reencode changed slots. */ Vector reencoding; for (Code c = 0; c < _encoding.size(); c++) reencoding.push_back(c); for (Slot *s = slots.begin(); s != slots.end(); s++) if (s->new_code >= 0) reencoding[s->old_code] = s->new_code; reencode(reencoding); check(); } void Metrics::make_base(int size) { Vector reencoding; for (Code c = 0; c < size && c < _encoding.size(); c++) { Char &ch = _encoding[c]; if (ch.base_code >= 0 && ch.base_code != c) { if (!reencoding.size()) for (Code cc = 0; cc < _encoding.size(); cc++) reencoding.push_back(cc); reencoding[ch.base_code] = c; reencoding[c] = ch.base_code; _encoding[c].swap(_encoding[ch.base_code]); } if (ch.virtual_char) // remove it ch.clear(); } if (reencoding.size()) { reencode(reencoding); cut_encoding(size); } check(); } /*****************************************************************************/ /* output */ bool Metrics::need_virtual(int size) const { if (size > _encoding.size()) size = _encoding.size(); for (const Char *ch = _encoding.begin(); ch < _encoding.begin() + size; ch++) if (ch->glyph /* actually encoded */ && (ch->pdx || ch->pdy || ch->adx || ch->virtual_char)) return true; return false; } bool Metrics::need_base() { if (!_liveness_marked) mark_liveness(_encoding.size()); for (const Char *ch = _encoding.begin(); ch < _encoding.end(); ch++) if ((ch->flags & Char::BASE_LIVE) && ch->glyph != _boundary_glyph) return true; return false; } bool Metrics::setting(Code code, Vector &v, SettingMode sm) const { extern int letterspace; if (!(sm & SET_KEEP)) v.clear(); if (!valid_code(code) || _encoding[code].glyph == 0) return false; const Char &ch = _encoding[code]; if (const VirtualChar *vc = ch.virtual_char) { bool good = true; int font_number = 0; if (ch.pdx != 0 || ch.pdy != 0) v.push_back(Setting(Setting::MOVE, ch.pdx, ch.pdy)); for (const Setting *s = vc->setting.begin(); s != vc->setting.end(); s++) switch (s->op) { case Setting::MOVE: case Setting::RULE: case Setting::PUSH: case Setting::POP: case Setting::SPECIAL: v.push_back(*s); break; case Setting::FONT: v.push_back(*s); font_number = s->x; break; case Setting::SHOW: if (font_number == 0) good &= setting(s->x, v, (SettingMode)(sm | SET_KEEP)); else v.push_back(*s); break; case Setting::KERN: case Setting::KERNX: if (sm & SET_INTERMEDIATE) v.push_back(*s); else if (font_number == 0 && s > vc->setting.begin() && s + 1 < vc->setting.end() && s[-1].op == Setting::SHOW && s[1].op == Setting::SHOW) { int k = kern(s[-1].x, s[1].x); if (s->op == Setting::KERNX) k -= letterspace; if (k) v.push_back(Setting(Setting::MOVE, k, 0)); } break; } if (ch.pdy != 0 || ch.adx - ch.pdx != 0) v.push_back(Setting(Setting::MOVE, ch.adx - ch.pdx, -ch.pdy)); return good; } else if (ch.base_code >= 0) { if (ch.pdx != 0 || ch.pdy != 0) v.push_back(Setting(Setting::MOVE, ch.pdx, ch.pdy)); v.push_back(Setting(Setting::SHOW, ch.base_code, ch.glyph)); if (ch.pdy != 0 || ch.adx - ch.pdx != 0) v.push_back(Setting(Setting::MOVE, ch.adx - ch.pdx, -ch.pdy)); return true; } else return false; } int Metrics::ligatures(Code in1, Vector &in2, Vector &out, Vector &context) const { in2.clear(); out.clear(); context.clear(); const Char &in1ch = _encoding[in1]; for (const Ligature *l = in1ch.ligatures.begin(); l != in1ch.ligatures.end(); l++) { in2.push_back(l->in2); const Char &outch = _encoding[l->out]; if (outch.context_setting(in1, l->in2)) { if (in1 == outch.built_in1 && l->in2 == outch.built_in2) in2.pop_back(); else if (in1 == outch.built_in1) { out.push_back(outch.built_in2); context.push_back(-1); } else { out.push_back(outch.built_in1); context.push_back(1); } } else { out.push_back(l->out); context.push_back(0); } } return in2.size(); } int Metrics::kerns(Code in1, Vector &in2, Vector &kern) const { in2.clear(); kern.clear(); const Char &in1ch = _encoding[in1]; for (const Kern *k = in1ch.kerns.begin(); k != in1ch.kerns.end(); k++) if (k->kern != 0) { in2.push_back(k->in2); kern.push_back(k->kern); } return in2.size(); } /*****************************************************************************/ /* debugging */ void Metrics::unparse(const Char *ch) const { Code c; if (ch >= _encoding.begin() && ch < _encoding.end()) c = ch - _encoding.begin(); else c = -1; fprintf(stderr, "%4d/%s%s%s%s%s%s\n", c, code_str(c), (ch->flag(Char::LIVE) ? " [L]" : ""), (ch->flag(Char::BASE_LIVE) ? " [B]" : ""), (ch->flag(Char::CONTEXT_ONLY) ? " [C]" : ""), (ch->flag(Char::BUILT) ? " [!]" : ""), (ch->base_code >= 0 ? " " : "")); if (ch->base_code >= 0 && ch->base_code != c) fprintf(stderr, "\tBASE %d/%s\n", ch->base_code, code_str(ch->base_code)); if (const VirtualChar *vc = ch->virtual_char) { fprintf(stderr, "\t*"); int curfont = 0; for (const Setting *s = vc->setting.begin(); s != vc->setting.end(); s++) switch (s->op) { case Setting::FONT: fprintf(stderr, " {F%d}", s->x); curfont = s->x; break; case Setting::SHOW: fprintf(stderr, " %d", s->x); if (curfont == 0) fprintf(stderr, "/%s", code_str(s->x)); break; case Setting::KERN: fprintf(stderr, " <>"); break; case Setting::MOVE: fprintf(stderr, " <%+d,%+d>", s->x, s->y); break; case Setting::RULE: fprintf(stderr, " [%d,%d]", s->x, s->y); break; case Setting::PUSH: fprintf(stderr, " ("); break; case Setting::POP: fprintf(stderr, " )"); break; case Setting::SPECIAL: fprintf(stderr, " S{%s}", s->s.c_str()); break; } fprintf(stderr, " ((%d/%s, %d/%s))\n", ch->built_in1, code_str(ch->built_in1), ch->built_in2, code_str(ch->built_in2)); } for (const Ligature *l = ch->ligatures.begin(); l != ch->ligatures.end(); l++) fprintf(stderr, "\t[%d/%s => %d/%s]%s\n", l->in2, code_str(l->in2), l->out, code_str(l->out), (_encoding[l->out].context_setting(c, l->in2) ? " [C]" : "")); #if 0 for (const Kern *k = ch->kerns.begin(); k != ch->kerns.end(); k++) fprintf(stderr, "\t{%d/%s %+d}\n", k->in2, code_str(k->in2), k->kern); #endif } void Metrics::unparse() const { for (const Char *ch = _encoding.begin(); ch < _encoding.end(); ch++) if (ch->glyph) unparse(ch); } lcdf-typetools-2.108/otftotfm/secondary.hh0000644000175000017500000001163013423375330015573 00000000000000#ifndef OTFTOTFM_SECONDARY_HH #define OTFTOTFM_SECONDARY_HH #include #include #include "setting.hh" class Metrics; class Secondary; class Transform; namespace Efont { class TrueTypeBoundsCharstringProgram; } struct FontInfo { const Efont::OpenType::Font *otf; const Efont::OpenType::Cmap *cmap; Efont::Cff *cff_file; const Efont::Cff::Font *cff; const Efont::OpenType::Post *post; const Efont::OpenType::Name *name; FontInfo(const Efont::OpenType::Font *otf, ErrorHandler *); ~FontInfo(); bool ok() const; int nglyphs() const { return _nglyphs; } bool glyph_names(Vector &) const; int glyphid(PermString) const; const Efont::CharstringProgram *program() const; int units_per_em() const { return program()->units_per_em(); } bool is_fixed_pitch() const; double italic_angle() const; double x_height(const Transform& font_xform) const; void set_is_fixed_pitch(bool is_fixed_pitch) { _override_is_fixed_pitch = true; _is_fixed_pitch = is_fixed_pitch; } void set_italic_angle(double italic_angle) { _override_italic_angle = true; _italic_angle = italic_angle; } enum { x_height_auto = 0, x_height_explicit, x_height_os2, x_height_x }; void set_x_height(int source, double x_height) { _override_x_height = source; _x_height = x_height; } String family_name() const; String postscript_name() const; private: int _nglyphs; mutable Vector _glyph_names; mutable bool _got_glyph_names; mutable Vector _unicodes; mutable Efont::TrueTypeBoundsCharstringProgram *_ttb_program; bool _override_is_fixed_pitch; bool _override_italic_angle; bool _is_fixed_pitch; uint8_t _override_x_height; double _italic_angle; double _x_height; }; class SettingSet { public: inline SettingSet(Secondary* s, Metrics& m); inline SettingSet& push_back(Setting s); inline SettingSet& push_back(int op, int x = 0, int y = 0); inline SettingSet& move(int x, int y = 0); SettingSet& show(int uni); inline SettingSet& kernx(bool is_kernx); inline bool check(); inline void checkpoint(); inline Metrics& metrics() const; inline const Vector& settings() const; private: Secondary* s_; Vector v_; int original_size_; Metrics& metrics_; int kern_type_; bool ok_; typedef Efont::OpenType::Glyph Glyph; }; class Secondary { public: Secondary(const FontInfo& finfo) : _finfo(finfo), _next(0) { } virtual ~Secondary(); void set_next(Secondary *s) { _next = s; } typedef Efont::OpenType::Glyph Glyph; bool encode_uni(int code, PermString name, const uint32_t* uni_first, const uint32_t* uni_last, Metrics &metrics, ErrorHandler *errh); inline bool encode_uni(int code, PermString name, uint32_t uni, Metrics& m, ErrorHandler* errh); virtual int setting(uint32_t uni, SettingSet&, ErrorHandler *); protected: const FontInfo& _finfo; friend class SettingSet; private: Secondary *_next; }; class T1Secondary : public Secondary { public: T1Secondary(const FontInfo &, const String &font_name, const String &otf_file_name); int setting(uint32_t uni, SettingSet&, ErrorHandler *); private: String _font_name; String _otf_file_name; int _units_per_em; int _xheight; int _spacewidth; enum { J_NODOT = -1031892 /* unlikely value */ }; int dotlessj_font(Metrics &, ErrorHandler *, Glyph &dj_glyph); }; bool char_bounds(double bounds[4], double& width, const FontInfo &, const Transform &, uint32_t uni); double char_one_bound(const FontInfo &, const Transform &, int dimen, bool max, double best, int uni, ...); inline SettingSet::SettingSet(Secondary* s, Metrics& m) : s_(s), original_size_(0), metrics_(m), kern_type_(Setting::KERN), ok_(true) { } inline SettingSet& SettingSet::kernx(bool is_kernx) { kern_type_ = is_kernx ? Setting::KERNX : Setting::KERN; return *this; } inline SettingSet& SettingSet::push_back(Setting s) { if (ok_) v_.push_back(s); return *this; } inline SettingSet& SettingSet::push_back(int op, int x, int y) { return push_back(Setting(op, x, y)); } inline SettingSet& SettingSet::move(int x, int y) { return push_back(Setting(Setting::MOVE, x, y)); } inline bool SettingSet::check() { bool ok = ok_; ok_ = true; return ok; } inline void SettingSet::checkpoint() { assert(ok_); original_size_ = v_.size(); } inline Metrics& SettingSet::metrics() const { return metrics_; } inline const Vector& SettingSet::settings() const { return v_; } inline bool Secondary::encode_uni(int code, PermString name, uint32_t uni, Metrics& m, ErrorHandler* errh) { return encode_uni(code, name, &uni, &uni + 1, m, errh); } #endif lcdf-typetools-2.108/otftotfm/glyphfilter.cc0000644000175000017500000001606513423375330016132 00000000000000/* glyphfilter.{cc,hh} -- define subsets of characters * * Copyright (c) 2004-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #ifdef WIN32 # define _USE_MATH_DEFINES #endif #include "glyphfilter.hh" #include #include #include #include #include "uniprop.hh" #include "util.hh" bool GlyphFilter::allow(Efont::OpenType::Glyph glyph, const Vector& glyph_names, uint32_t unicode, int ptype) const { // out-of-range glyphs never match if (glyph < 0 || glyph >= glyph_names.size()) return false; String glyph_name = glyph_names[glyph]; int uniprop = -1; bool any_includes = false; bool included = false; // loop over patterns for (const Pattern* p = _patterns.begin(); p < _patterns.end(); p++) { // check pattern type if ((p->type & ~T_TYPEMASK) != ptype) continue; // check include/exclude if ((p->type & T_EXCLUDE) == 0) { if (included) continue; any_includes = true; } // check if there's a match bool match; if (p->data == D_NAME) match = glob_match(glyph_name, p->pattern); else if (p->data == D_UNIPROP) { if (uniprop < 0) uniprop = UnicodeProperty::property(unicode); match = ((uniprop & p->u.uniprop.mask) == p->u.uniprop.value); } else match = (unicode >= p->u.unirange.low && unicode <= p->u.unirange.high); // act if match if (match == ((p->type & T_NEGATE) == 0)) { if ((p->type & T_EXCLUDE) == 0) included = true; else return false; } } return !any_includes || included; } GlyphFilter::Pattern::Pattern(uint16_t ptype) : type(ptype), data(D_NAME) { // make sure that even unused data has a known value, to simplify // operator== u.unirange.low = u.unirange.high = 0; } int GlyphFilter::Pattern::compare(const GlyphFilter::Pattern& a, const GlyphFilter::Pattern& b) { int cmp = a.type - b.type; if (cmp == 0) cmp = a.data - b.data; if (cmp == 0) cmp = (int) (a.u.unirange.low - b.u.unirange.low); if (cmp == 0) cmp = (int) (a.u.unirange.high - b.u.unirange.high); if (cmp == 0) cmp = String::compare(a.pattern, b.pattern); return cmp; } void GlyphFilter::add_pattern(const String& pattern, int ptype, ErrorHandler* errh) { _sorted = false; const char* begin = pattern.begin(); const char* end = pattern.end(); while (begin < end && isspace((unsigned char) *begin)) begin++; if (begin >= end) errh->error("missing pattern"); while (begin < end) { const char* word = begin; while (word < end && !isspace((unsigned char) *word)) word++; bool negated = false; if (begin < word && begin[0] == '!') negated = true, begin++; // actually parse clause Pattern p(ptype + (negated ? T_NEGATE : 0)); // unicode property if (begin + 3 <= word && begin[0] == '<' && word[-1] == '>') { p.data = D_UNIPROP; if (UnicodeProperty::parse_property(pattern.substring(begin + 1, word - 1), p.u.uniprop.value, p.u.uniprop.mask)) _patterns.push_back(p); else if (errh) errh->error("unknown Unicode property %<%s%>", pattern.c_str()); goto next_clause; } // unicode values { const char* dash = std::find(begin, word, '-'); if (parse_unicode_number(begin, dash, 2, p.u.unirange.low)) { if (dash == word) p.u.unirange.high = p.u.unirange.low; else if (dash == word - 1) p.u.unirange.high = 0xFFFFFFFFU; else if (parse_unicode_number(dash + 1, word, (begin[0] == 'U' ? 1 : 0), p.u.unirange.high)) /* do nothing */; else goto name_pattern; // assume it's a name p.data = D_UNIRANGE; _patterns.push_back(p); goto next_clause; } } // otherwise must be name pattern name_pattern: p.data = D_NAME; p.pattern = pattern.substring(begin, word); _patterns.push_back(p); // move to next clause next_clause: for (begin = word; begin < end && isspace((unsigned char) *begin); begin++) /* nada */; } } void GlyphFilter::add_substitution_filter(const String& s, bool is_exclude, ErrorHandler* errh) { add_pattern(s, is_exclude ? T_SRC + T_EXCLUDE : T_SRC, errh); } void GlyphFilter::add_alternate_filter(const String& s, bool is_exclude, ErrorHandler* errh) { add_pattern(s, is_exclude ? T_DST + T_EXCLUDE : T_DST, errh); } GlyphFilter& GlyphFilter::operator+=(const GlyphFilter& gf) { // be careful about self-addition _patterns.reserve(gf._patterns.size()); const Pattern* end = gf._patterns.end(); for (const Pattern* p = gf._patterns.begin(); p < end; p++) _patterns.push_back(*p); return *this; } GlyphFilter operator+(const GlyphFilter& a, const GlyphFilter& b) { if (!b) return a; if (!a) return b; GlyphFilter x(a); x += b; return x; } bool operator==(const GlyphFilter& a, const GlyphFilter& b) { if (&a == &b) return true; if (a._patterns.size() != b._patterns.size()) return false; const GlyphFilter::Pattern* pa = a._patterns.begin(); const GlyphFilter::Pattern* pb = b._patterns.begin(); for (; pa < a._patterns.end(); pa++, pb++) if (!(*pa == *pb)) return false; return true; } void GlyphFilter::sort() { if (!_sorted) { std::sort(_patterns.begin(), _patterns.end()); Pattern* true_end = std::unique(_patterns.begin(), _patterns.end()); _patterns.erase(true_end, _patterns.end()); _sorted = true; } } void GlyphFilter::unparse(StringAccum& sa) const { for (const Pattern* p = _patterns.begin(); p < _patterns.end(); p++) { sa << (p->type & T_DST ? 'D' : 'S') << (p->type & T_NEGATE ? "!" : "") << (p->type & T_EXCLUDE ? "X" : ""); if (p->data == D_NAME) sa << '<' << p->pattern << '>'; else if (p->data == D_UNIPROP) sa << "[UNIPROP:" << p->u.uniprop.mask << '=' << p->u.uniprop.value << ']'; else sa.snprintf(20, "[U+%02x-U+%02x]", p->u.unirange.low, p->u.unirange.high); sa << ' '; } if (_patterns.size()) sa.pop_back(); } lcdf-typetools-2.108/otftotfm/otftotfm.cc0000644000175000017500000026452413423375330015450 00000000000000/* otftotfm.cc -- driver for translating OpenType fonts to TeX metrics * * Copyright (c) 2003-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #ifdef WIN32 # define _USE_MATH_DEFINES #endif #include #include #include #include #include #include #include #include #include #include "glyphfilter.hh" #include "metrics.hh" #include "dvipsencoding.hh" #include "automatic.hh" #include "secondary.hh" #include "kpseinterface.h" #include "util.hh" #include "otftotfm.hh" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* M_PI isn't defined in C99 */ #ifndef M_PI # define M_PI 3.14159265358979323846264338327 #endif #ifdef HAVE_CTIME # include #endif #ifdef HAVE_UNISTD_H # include #endif #ifdef HAVE_FCNTL_H # include #endif using namespace Efont; #define VERSION_OPT 301 #define HELP_OPT 302 #define QUERY_SCRIPTS_OPT 303 #define QUERY_FEATURES_OPT 304 #define KPATHSEA_DEBUG_OPT 305 #define SCRIPT_OPT 311 #define FEATURE_OPT 312 #define ENCODING_OPT 313 #define LITERAL_ENCODING_OPT 314 #define EXTEND_OPT 315 #define SLANT_OPT 316 #define LETTERSPACE_OPT 317 #define LIGKERN_OPT 318 #define CODINGSCHEME_OPT 319 #define UNICODING_OPT 320 #define BOUNDARY_CHAR_OPT 321 #define DESIGN_SIZE_OPT 322 #define MINIMUM_KERN_OPT 323 #define ALTSELECTOR_CHAR_OPT 324 #define INCLUDE_ALTERNATES_OPT 325 #define EXCLUDE_ALTERNATES_OPT 326 #define CLEAR_ALTERNATES_OPT 327 #define ALTSELECTOR_FEATURE_OPT 328 #define DEFAULT_LIGKERN_OPT 329 #define NO_ECOMMAND_OPT 330 #define LETTER_FEATURE_OPT 331 #define INCLUDE_SUBS_OPT 332 #define EXCLUDE_SUBS_OPT 333 #define CLEAR_SUBS_OPT 334 #define SUBS_FILTER_OPT 335 #define ALTERNATES_FILTER_OPT 336 #define SPACE_FACTOR_OPT 337 #define MATH_SPACING_OPT 338 #define POSITION_OPT 339 #define WARN_MISSING_OPT 340 #define BASE_ENCODINGS_OPT 341 #define FIXED_PITCH_OPT 342 #define ITALIC_ANGLE_OPT 343 #define PROPORTIONAL_WIDTH_OPT 344 #define X_HEIGHT_OPT 345 #define AUTOMATIC_OPT 350 #define FONT_NAME_OPT 351 #define QUIET_OPT 352 #define GLYPHLIST_OPT 353 #define VENDOR_OPT 354 #define TYPEFACE_OPT 355 #define NOCREATE_OPT 356 #define VERBOSE_OPT 357 #define FORCE_OPT 358 #define VIRTUAL_OPT 360 #define PL_OPT 361 #define TFM_OPT 362 #define MAP_FILE_OPT 363 #define OUTPUT_ENCODING_OPT 364 #define DIR_OPTS 380 #define ENCODING_DIR_OPT (DIR_OPTS + O_ENCODING) #define TFM_DIR_OPT (DIR_OPTS + O_TFM) #define PL_DIR_OPT (DIR_OPTS + O_PL) #define VF_DIR_OPT (DIR_OPTS + O_VF) #define VPL_DIR_OPT (DIR_OPTS + O_VPL) #define TYPE1_DIR_OPT (DIR_OPTS + O_TYPE1) #define TYPE42_DIR_OPT (DIR_OPTS + O_TYPE42) #define TRUETYPE_DIR_OPT (DIR_OPTS + O_TRUETYPE) #define DIR_OPT (DIR_OPTS + NUMODIR) #define NO_OUTPUT_OPTS 400 #define NO_ENCODING_OPT (NO_OUTPUT_OPTS + G_ENCODING) #define NO_TYPE1_OPT (NO_OUTPUT_OPTS + G_TYPE1) #define NO_DOTLESSJ_OPT (NO_OUTPUT_OPTS + G_DOTLESSJ) #define NO_UPDMAP_OPT (NO_OUTPUT_OPTS + G_UPDMAP) #define UPDMAP_SYS_OPT (NO_OUTPUT_OPTS + G_UPDMAP_USER) #define YES_OUTPUT_OPTS 2000 #define TRUETYPE_OPT (YES_OUTPUT_OPTS + G_TRUETYPE) #define TYPE42_OPT (YES_OUTPUT_OPTS + G_TYPE42) #define UPDMAP_USER_OPT (YES_OUTPUT_OPTS + G_UPDMAP_USER) #define CHAR_OPTTYPE (Clp_ValFirstUser) static Clp_Option options[] = { { "script", 's', SCRIPT_OPT, Clp_ValString, 0 }, { "feature", 'f', FEATURE_OPT, Clp_ValString, 0 }, { "letter-feature", 0, LETTER_FEATURE_OPT, Clp_ValString, 0 }, { "lf", 0, LETTER_FEATURE_OPT, Clp_ValString, 0 }, { "include-substitutions", 0, INCLUDE_SUBS_OPT, Clp_ValString, 0 }, { "exclude-substitutions", 0, EXCLUDE_SUBS_OPT, Clp_ValString, 0 }, { "clear-substitutions", 0, CLEAR_SUBS_OPT, 0, 0 }, { "substitution-filter", 0, SUBS_FILTER_OPT, Clp_ValString, 0 }, { "subs-filter", 0, SUBS_FILTER_OPT, Clp_ValString, 0 }, { "encoding", 'e', ENCODING_OPT, Clp_ValString, 0 }, { "literal-encoding", 0, LITERAL_ENCODING_OPT, Clp_ValString, 0 }, { "base-encodings", 0, BASE_ENCODINGS_OPT, Clp_ValString, 0 }, { "extend", 'E', EXTEND_OPT, Clp_ValDouble, 0 }, { "slant", 'S', SLANT_OPT, Clp_ValDouble, 0 }, { "letterspacing", 'L', LETTERSPACE_OPT, Clp_ValInt, 0 }, { "letterspace", 'L', LETTERSPACE_OPT, Clp_ValInt, 0 }, { "min-kern", 'k', MINIMUM_KERN_OPT, Clp_ValDouble, 0 }, { "minimum-kern", 'k', MINIMUM_KERN_OPT, Clp_ValDouble, 0 }, { "kern-precision", 'k', MINIMUM_KERN_OPT, Clp_ValDouble, 0 }, { "ligkern", 0, LIGKERN_OPT, Clp_ValString, 0 }, { "position", 0, POSITION_OPT, Clp_ValString, 0 }, { "warn-missing", 0, WARN_MISSING_OPT, 0, Clp_Negate }, { "no-encoding-commands", 0, NO_ECOMMAND_OPT, 0, 0 }, { "default-ligkern", 0, DEFAULT_LIGKERN_OPT, 0, Clp_Negate }, { "unicoding", 0, UNICODING_OPT, Clp_ValString, 0 }, { "coding-scheme", 0, CODINGSCHEME_OPT, Clp_ValString, 0 }, { "boundary-char", 0, BOUNDARY_CHAR_OPT, CHAR_OPTTYPE, 0 }, { "altselector", 0, ALTSELECTOR_CHAR_OPT, CHAR_OPTTYPE, Clp_PreferredMatch }, { "altselector-char", 0, ALTSELECTOR_CHAR_OPT, CHAR_OPTTYPE, 0 }, { "altselector-feature", 0, ALTSELECTOR_FEATURE_OPT, Clp_ValString, 0 }, { "design-size", 0, DESIGN_SIZE_OPT, Clp_ValDouble, 0 }, { "include-alternates", 0, INCLUDE_ALTERNATES_OPT, Clp_ValString, 0 }, { "exclude-alternates", 0, EXCLUDE_ALTERNATES_OPT, Clp_ValString, 0 }, { "clear-alternates", 0, CLEAR_ALTERNATES_OPT, 0, 0 }, { "alternates-filter", 0, ALTERNATES_FILTER_OPT, Clp_ValString, 0 }, { "space-factor", 0, SPACE_FACTOR_OPT, Clp_ValDouble, 0 }, { "math-spacing", 0, MATH_SPACING_OPT, CHAR_OPTTYPE, Clp_Negate | Clp_Optional }, { "fixed-pitch", 0, FIXED_PITCH_OPT, 0, Clp_Negate }, { "fixed-width", 0, FIXED_PITCH_OPT, 0, Clp_Negate }, { "proportional-width", 0, PROPORTIONAL_WIDTH_OPT, 0, Clp_Negate }, { "italic-angle", 0, ITALIC_ANGLE_OPT, Clp_ValDouble, 0 }, { "x-height", 0, X_HEIGHT_OPT, Clp_ValString, 0 }, { "pl", 'p', PL_OPT, 0, Clp_Negate }, { "tfm", 't', TFM_OPT, 0, Clp_Negate }, // not in documentation { "virtual", 0, VIRTUAL_OPT, 0, Clp_Negate }, { "no-encoding", 0, NO_ENCODING_OPT, 0, 0 }, { "no-type1", 0, NO_TYPE1_OPT, 0, 0 }, { "no-dotlessj", 0, NO_DOTLESSJ_OPT, 0, 0 }, { "no-updmap", 0, NO_UPDMAP_OPT, 0, 0 }, { "updmap-sys", 0, UPDMAP_SYS_OPT, 0, 0 }, { "updmap-user", 0, UPDMAP_USER_OPT, 0, 0 }, { "truetype", 0, TRUETYPE_OPT, 0, Clp_Negate }, { "type42", 0, TYPE42_OPT, 0, Clp_Negate }, { "map-file", 0, MAP_FILE_OPT, Clp_ValString, Clp_Negate }, { "output-encoding", 0, OUTPUT_ENCODING_OPT, Clp_ValString, Clp_Optional }, { "automatic", 'a', AUTOMATIC_OPT, 0, Clp_Negate }, { "name", 'n', FONT_NAME_OPT, Clp_ValString, 0 }, { "vendor", 'v', VENDOR_OPT, Clp_ValString, 0 }, { "typeface", 0, TYPEFACE_OPT, Clp_ValString, 0 }, { "directory", 0, DIR_OPT, Clp_ValString, 0 }, { "encoding-directory", 0, ENCODING_DIR_OPT, Clp_ValString, 0 }, { "pl-directory", 0, PL_DIR_OPT, Clp_ValString, 0 }, { "tfm-directory", 0, TFM_DIR_OPT, Clp_ValString, 0 }, { "vpl-directory", 0, VPL_DIR_OPT, Clp_ValString, 0 }, { "vf-directory", 0, VF_DIR_OPT, Clp_ValString, 0 }, { "type1-directory", 0, TYPE1_DIR_OPT, Clp_ValString, 0 }, { "type42-directory", 0, TYPE42_DIR_OPT, Clp_ValString, 0 }, { "truetype-directory", 0, TRUETYPE_DIR_OPT, Clp_ValString, 0 }, { "quiet", 'q', QUIET_OPT, 0, Clp_Negate }, { "glyphlist", 0, GLYPHLIST_OPT, Clp_ValString, 0 }, { "no-create", 0, NOCREATE_OPT, 0, 0 }, { "force", 0, FORCE_OPT, 0, Clp_Negate }, { "verbose", 'V', VERBOSE_OPT, 0, Clp_Negate }, { "kpathsea-debug", 0, KPATHSEA_DEBUG_OPT, Clp_ValInt, 0 }, { "help", 'h', HELP_OPT, 0, 0 }, { "version", 0, VERSION_OPT, 0, 0 }, { "query-features", 0, QUERY_FEATURES_OPT, 0, 0 }, { "qf", 0, QUERY_FEATURES_OPT, 0, 0 }, { "query-scripts", 0, QUERY_SCRIPTS_OPT, 0, 0 }, { "qs", 0, QUERY_SCRIPTS_OPT, 0, 0 }, }; static const char * const default_ligkerns = "\ space l =: lslash ; space L =: Lslash ; \ question quoteleft =: questiondown ; \ exclam quoteleft =: exclamdown ; \ hyphen hyphen =: endash ; endash hyphen =: emdash ; \ quoteleft quoteleft =: quotedblleft ; \ quoteright quoteright =: quotedblright ;"; struct BaseEncoding { String font_name; String secondary; DvipsEncoding encoding; }; static const char *program_name; static String current_time; static StringAccum invocation; static PermString::Initializer perm_initializer; static PermString dot_notdef(".notdef"); static Vector interesting_scripts; static Vector interesting_features; static Vector altselector_features; static GlyphFilter null_filter; static HashMap feature_filters(0); static HashMap altselector_feature_filters(0); static String font_name; static String encoding_file; static Vector base_encodings; static double extend; static double slant; int letterspace; static double design_size; static double minimum_kern = 2.0; static double space_factor = 1.0; static bool math_spacing = false; static int skew_char = -1; static bool override_is_fixed_pitch = false; static bool is_fixed_pitch; static bool override_italic_angle = false; static double italic_angle; static int override_x_height = FontInfo::x_height_auto; static double x_height; static String out_encoding_file; static String out_encoding_name; unsigned output_flags = G_ENCODING | G_METRICS | G_VMETRICS | G_PSFONTSMAP | G_TYPE1 | G_DOTLESSJ | G_UPDMAP | G_TRUETYPE; bool automatic = false; bool verbose = false; bool no_create = false; bool quiet = false; bool force = false; static String otf_data; void usage_error(ErrorHandler *errh, const char *error_message, ...) { va_list val; va_start(val, error_message); if (!error_message) errh->message("Usage: %s [OPTION]... FONT", program_name); else errh->xmessage(ErrorHandler::e_error, error_message, val); errh->message("Type %s --help for more information.", program_name); exit(1); } void usage() { FileErrorHandler uerrh(stdout); uerrh.message("\ % generates TeX font metrics files from an OpenType font (PostScript\n\ flavor only), including ligatures, kerns, and some positionings. Supply\n\ %<-s SCRIPT[.LANG]%> options to specify a language system, %<-f FEAT%> options to\n\ turn on optional OpenType features, and a %<-e ENC%> option to specify a base\n\ encoding. Output files are written to the current directory (but see\n\ %<--automatic%> and the % options).\n\ \n\ Usage: %s [-a] [OPTIONS] OTFFILE FONTNAME\n\n", program_name); uerrh.message("\ Font feature and transformation options:\n\ -s, --script=SCRIPT[.LANG] Use features for script SCRIPT[.LANG] [latn].\n\ -f, --feature=FEAT Activate feature FEAT.\n\ --lf, --letter-feature=FEAT Activate feature FEAT for letters.\n\ --subs-filter=PAT Substitute only characters matching PAT.\n\ --include-subs=PAT Same, but cumulative.\n\ --exclude-subs=PAT Don%,t substitute characters matching PAT.\n\ --clear-subs Clear included/excluded substitutions.\n\ -E, --extend=F Widen characters by a factor of F.\n\ -S, --slant=AMT Oblique characters by AMT, generally <<1.\n\ -L, --letterspacing=AMT Letterspace each character by AMT units.\n\ --math-spacing[=SKEWCH] Use letterspacing appropriate for math.\n\ -k, --min-kern=N Omit kerns with absolute value < N [2.0].\n\ --space-factor=F Scale wordspace by a factor of F.\n\ --design-size=SIZE Set font design size to SIZE.\n\ --fixed-width Set fixed width (no space stretch).\n\ --italic-angle=ANGLE Set font italic angle (for positioning accents).\n\ --x-height=AMT Set x-height to AMT units.\n\ \n"); uerrh.message("\ Encoding options:\n\ -e, --encoding=FILE Use DVIPS encoding FILE as a base encoding.\n\ --boundary-char=CHAR Set the boundary character to CHAR.\n\ --altselector-char=CHAR Set the alternate selector character to CHAR.\n\ --altselector-feature=F Activate feature F for --altselector-char.\n\ --alternates-filter=PAT Include only alternate characters matching PAT.\n\ --include-alternates=PAT Same as --alternates-filter, but cumulative.\n\ --exclude-alternates=PAT Ignore alternate characters matching PAT.\n\ --clear-alternates Clear included/excluded alternates.\n\ --ligkern=COMMAND Add a ligature or kern.\n\ --position=COMMAND Add a POSITION command.\n\ --unicoding=COMMAND Add a UNICODING command.\n\ --no-encoding-commands Ignore encoding file%,s LIGKERN/UNICODINGs.\n\ --no-default-ligkern Don%,t include default LIGKERNs.\n\ --coding-scheme=SCHEME Set the output coding scheme to SCHEME.\n\ --warn-missing Warn about characters not supported by font.\n\ --literal-encoding=FILE Use DVIPS encoding FILE verbatim.\n\ --base-encodings=FILE Output can refer to base fonts named in FILE.\n\ \n"); uerrh.message("\ Automatic mode options:\n\ -a, --automatic Install in a TeX Directory Structure.\n\ -v, --vendor=NAME Set font vendor for TDS [lcdftools].\n\ --typeface=NAME Set typeface name for TDS [].\n\ --no-type1 Do not generate Type 1 fonts.\n\ --no-dotlessj Do not generate dotless-j fonts.\n\ --no-truetype Do not install TrueType-flavored input fonts.\n\ --no-updmap Do not run updmap.\n\ --updmap-user Run `updmap-user` instead of `updmap-sys`.\n\ \n\ Output options:\n\ -n, --name=NAME Generated font name is NAME.\n\ -p, --pl Output human-readable PL/VPLs, not TFM/VFs.\n\ --no-virtual Do not generate VFs or VPLs.\n\ --no-encoding Do not generate an encoding file.\n\ --no-map Do not generate a psfonts.map line.\n\ --output-encoding[=FILE] Only generate an encoding file.\n\ \n"); uerrh.message("\ File location options:\n\ --tfm-directory=DIR Put TFM files in DIR [.|automatic].\n\ --pl-directory=DIR Put PL files in DIR [.|automatic].\n\ --vf-directory=DIR Put VF files in DIR [.|automatic].\n\ --vpl-directory=DIR Put VPL files in DIR [.|automatic].\n\ --encoding-directory=DIR Put encoding files in DIR [.|automatic].\n\ --type1-directory=DIR Put Type 1 fonts in DIR [automatic].\n\ --truetype-directory=DIR Put TrueType fonts in DIR [automatic].\n\ --directory=DIR Put output in DIR [.|automatic].\n\ --map-file=FILE Update FILE with psfonts.map information [-].\n\ \n\ Other options:\n\ --glyphlist=FILE Use FILE to map Adobe glyph names to Unicode.\n\ -V, --verbose Print progress information to standard error.\n\ --no-create Print messages, don't modify any files.\n\ --force Generate files even if versions already exist.\n" #if HAVE_KPATHSEA " --kpathsea-debug=MASK Set path searching debug flags to MASK.\n" #endif " -h, --help Print this message and exit.\n\ -q, --quiet Do not generate any error messages.\n\ --version Print version number and exit.\n\ \n\ Report bugs to .\n"); } #ifndef WIN32 extern "C" { static void sigchld_handler(int s) { #if !HAVE_SIGACTION signal(s, sigchld_handler); #else (void) s; #endif } } static void handle_sigchld() { #ifdef SIGCHLD int sigchld = SIGCHLD; #else int sigchld = SIGCLD; #endif #if HAVE_SIGACTION struct sigaction sa; sigaction(sigchld, 0, &sa); sa.sa_handler = sigchld_handler; sa.sa_flags = 0; sigaction(sigchld, &sa, 0); #else signal(sigchld, sigchld_handler); #endif } #endif // MAIN String suffix_font_name(const String &font_name, const String &suffix) { const char *begin = font_name.begin(), *end = font_name.end(); while (end > begin && isdigit((unsigned char) end[-1])) --end; if (end < font_name.end() && end > begin && end[-1] != '-' && end[-1] != '+') end = font_name.end(); else while (end > begin && (end[-1] == '-' || end[-1] == '+')) --end; if (end == begin) end = font_name.end(); return font_name.substring(begin, end) + suffix + font_name.substring(end, font_name.end()); } static inline String make_base_font_name(const String &font_name) { return suffix_font_name(font_name, "--base"); } static double get_design_size(const FontInfo &finfo) { try { String gpos_table = finfo.otf->table("GPOS"); if (!gpos_table) throw OpenType::Error(); ErrorHandler *errh = ErrorHandler::silent_handler(); OpenType::Gpos gpos(gpos_table, errh); // extract 'size' feature(s) int required_fid; Vector fids; for (const OpenType::Tag *t = interesting_scripts.begin(); t < interesting_scripts.end(); t += 2) gpos.script_list().features(t[0], t[1], required_fid, fids, 0, false); int size_fid = gpos.feature_list().find(OpenType::Tag("size"), fids); if (size_fid < 0) throw OpenType::Error(); // old Adobe fonts implement an old, incorrect idea // of what the FeatureParams offset means. OpenType::Name name(finfo.otf->table("name"), errh); OpenType::Data size_data = gpos.feature_list().size_params(size_fid, name, errh); if (!size_data.length()) throw OpenType::Error(); double result = size_data.u16(0) / 10.; // check for insane design sizes if (result < 1 || result > 1000) throw OpenType::Error(); // return a number in 'pt', not 'bp' return result * 72.27 / 72.; } catch (OpenType::Error) { return 10.0; } } static const char * const digit_names[] = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; static inline const char * lig_context_str(int ctx) { return (ctx == 0 ? "LIG" : (ctx < 0 ? "/LIG" : "LIG/")); } static double max_printed_real; namespace { struct Printer { Printer(FILE* f, unsigned design_units, unsigned units_per_em) : f_(f), du_((double) design_units / units_per_em), round_(design_units == 1000) { } inline double transform(double value) const; void print_transformed(const char* prefix, double value) const; void print(const char* prefix, double value) const; String render(double value) const; FILE* f_; double du_; bool round_; }; inline double Printer::transform(double value) const { value *= du_; if (round_) value = ceil(value); return value; } void Printer::print_transformed(const char* prefix, double value) const { if (round_ || value == 0 || (value > 0.01 && value - floor(value) < 0.01)) fprintf(f_, "%s R %g)\n", prefix, value); else fprintf(f_, "%s R %.4f)\n", prefix, value); max_printed_real = std::max(max_printed_real, fabs(value)); } void Printer::print(const char* prefix, double value) const { print_transformed(prefix, transform(value)); } String Printer::render(double value) const { value = transform(value); if (round_ || value == 0 || (value > 0.01 && value - floor(value) < 0.01)) return String(value); else { char buf[128]; sprintf(buf, "%.4f", value); return String(buf); } } } // namespace double font_slant(const FontInfo &finfo) { double val = finfo.italic_angle(); return -tan(val * M_PI / 180.0) + slant; } static void output_pl(Metrics &metrics, const String &ps_name, int boundary_char, const FontInfo &finfo, bool vpl, const String &filename, ErrorHandler *errh) { // create file if (no_create) { errh->message("would create %s", filename.c_str()); return; } if (verbose) errh->message("creating %s", filename.c_str()); FILE *f = fopen(filename.c_str(), "w"); if (!f) { errh->error("%s: %s", filename.c_str(), strerror(errno)); return; } // XXX check DESIGNSIZE and DESIGNUNITS for correctness fprintf(f, "(COMMENT Created by '%s'%s)\n", invocation.c_str(), current_time.c_str()); // calculate a TeX FAMILY name using afm2tfm's algorithm String family_name = String("TeX-") + ps_name; if (family_name.length() > 19) family_name = family_name.substring(0, 9) + family_name.substring(-10); fprintf(f, "(FAMILY %s)\n", family_name.c_str()); if (metrics.coding_scheme()) fprintf(f, "(CODINGSCHEME %.39s)\n", String(metrics.coding_scheme()).c_str()); int design_units = metrics.design_units(); if (design_size <= 0) design_size = get_design_size(finfo); max_printed_real = 0; fprintf(f, "(DESIGNSIZE R %.1f)\n" "(DESIGNUNITS R %d.0)\n" "(COMMENT DESIGNSIZE (1 em) IS IN POINTS)\n" "(COMMENT OTHER DIMENSIONS ARE MULTIPLES OF DESIGNSIZE/%d)\n" "(FONTDIMEN\n", design_size, design_units, design_units); // figure out font dimensions Transform font_xform; if (extend) font_xform.scale(extend, 1); if (slant) font_xform.shear(slant); double bounds[4], width; Printer pr(f, design_units, metrics.units_per_em()); double actual_slant = font_slant(finfo); if (actual_slant) fprintf(f, " (SLANT R %g)\n", actual_slant); if (char_bounds(bounds, width, finfo, font_xform, ' ')) { // advance space width by letterspacing, scale by space_factor double space_width = (width + (vpl ? letterspace : 0)) * space_factor; pr.print(" (SPACE", space_width); if (finfo.is_fixed_pitch()) { // fixed-pitch: no space stretch or shrink pr.print(" (STRETCH", 0); pr.print(" (SHRINK", 0); pr.print(" (EXTRASPACE", space_width); } else { pr.print(" (STRETCH", space_width / 2.); pr.print(" (SHRINK", space_width / 3.); pr.print(" (EXTRASPACE", space_width / 6.); } } double x_height = finfo.x_height(font_xform); if (x_height < finfo.units_per_em()) pr.print(" (XHEIGHT", x_height); pr.print(" (QUAD", finfo.units_per_em()); fprintf(f, " )\n"); if (boundary_char >= 0) fprintf(f, "(BOUNDARYCHAR D %d)\n", boundary_char); // figure out font mapping int mapped_font0 = 0; Vector font_mapping; if (vpl) { int vpl_first_font = (metrics.need_base() ? 0 : 1); font_mapping.assign(metrics.n_mapped_fonts(), 0); if (vpl_first_font == 1 && font_mapping.size() == 1) font_mapping.push_back(0); // how many times is each font used? Vector settings; for (int i = 0; i < 256; i++) if (metrics.setting(i, settings)) { int font_number = 0; for (const Setting *s = settings.begin(); s < settings.end(); s++) if (s->op == Setting::SHOW) font_mapping[font_number]++; else if (s->op == Setting::FONT) font_number = (int) s->x; } // make sure the most-used font is number 0 mapped_font0 = std::max_element(font_mapping.begin(), font_mapping.end()) - font_mapping.begin(); // prepare the mapping for (int i = vpl_first_font; i < font_mapping.size(); i++) font_mapping[i] = i - vpl_first_font; font_mapping[mapped_font0] = 0; font_mapping[vpl_first_font] = mapped_font0 - vpl_first_font; if (vpl_first_font != 0) font_mapping[0] = font_mapping.size() - 1; // write MAPFONT for (int i = 0; i < metrics.n_mapped_fonts() - vpl_first_font; i++) { int j = std::find(font_mapping.begin(), font_mapping.end(), i) - font_mapping.begin(); String name = metrics.mapped_font_name(j); if (!name) name = make_base_font_name(font_name); fprintf(f, "(MAPFONT D %d\n (FONTNAME %s)\n (FONTDSIZE R %.1f)\n )\n", i, name.c_str(), design_size); } } else for (int i = 0; i < metrics.n_mapped_fonts(); i++) font_mapping.push_back(i); // figure out the proper names and numbers for glyphs Vector glyph_ids; Vector glyph_comments(257, String()); Vector glyph_base_comments(257, String()); for (int i = 0; i < metrics.encoding_size(); i++) { if (metrics.glyph(i)) { PermString name = metrics.code_name(i), expected_name; if (i >= '0' && i <= '9') expected_name = digit_names[i - '0']; else if ((i >= 'A' && i <= 'Z') || (i >= 'a' && i <= 'z')) expected_name = PermString((char)i); String glyph_comment; if (name != expected_name) glyph_comment = " (COMMENT " + String(name) + ")"; int base = metrics.base_code(i); if (base >= 0 && base < 256) glyph_base_comments[base] = glyph_comment; if (i >= 256) continue; char* expected_name_end; if (expected_name && (name == expected_name || (name.length() == 7 && memcmp(name.data(), "uni00", 5) == 0 && strtol(name.c_str() + 3, &expected_name_end, 16) == i && *expected_name_end == 0))) glyph_ids.push_back("C " + String((char)i)); else glyph_ids.push_back("D " + String(i)); glyph_comments[i] = glyph_base_comments[i] = glyph_comment; } else if (i < 256) glyph_ids.push_back("D " + String(i)); } // finally, BOUNDARYCHAR glyph_ids.push_back("BOUNDARYCHAR"); // LIGTABLE fprintf(f, "(LIGTABLE\n"); Vector lig_code2, lig_outcode, lig_context, kern_code2, kern_amt; // don't print KRN x after printing LIG x uint32_t used[8]; bool any_ligs = false; StringAccum omitted_clig_sa; for (int i = 0; i <= 256; i++) if (metrics.glyph(i) && minimum_kern < 10000) { int any_lig = metrics.ligatures(i, lig_code2, lig_outcode, lig_context); int any_kern = metrics.kerns(i, kern_code2, kern_amt); if (any_lig || any_kern) { StringAccum kern_sa; memset(used, 0, sizeof(used)); for (int j = 0; j < lig_code2.size(); j++) { if (lig_outcode[j] < 257) { kern_sa << " (" << lig_context_str(lig_context[j]) << ' ' << glyph_ids[lig_code2[j]] << ' ' << glyph_ids[lig_outcode[j]] << ')' << glyph_comments[lig_code2[j]] << glyph_comments[lig_outcode[j]] << '\n'; used[lig_code2[j] >> 5] |= (1 << (lig_code2[j] & 0x1F)); } else { omitted_clig_sa << "(COMMENT omitted " << lig_context_str(lig_context[j]) << ' ' << metrics.code_name(i) << ' ' << metrics.code_name(lig_code2[j]) << ' ' << metrics.code_name(lig_outcode[j]) << ")\n"; } } for (Vector::const_iterator k2 = kern_code2.begin(); k2 < kern_code2.end(); k2++) if (!(used[*k2 >> 5] & (1 << (*k2 & 0x1F)))) { double this_kern = kern_amt[k2 - kern_code2.begin()]; if (fabs(this_kern) >= minimum_kern) kern_sa << " (KRN " << glyph_ids[*k2] << " R " << pr.render(this_kern) << ')' << glyph_comments[*k2] << '\n'; } if (kern_sa) { if (any_ligs) fprintf(f, "\n"); fprintf(f, " (LABEL %s)%s\n%s (STOP)\n", glyph_ids[i].c_str(), glyph_comments[i].c_str(), kern_sa.c_str()); any_ligs = true; } } } fprintf(f, " )\n"); if (omitted_clig_sa) fprintf(f, "%s\n", omitted_clig_sa.c_str()); // CHARACTERs Vector settings; StringAccum sa; Vector push_stack; for (int i = 0; i < 256; i++) if (metrics.setting(i, settings)) { fprintf(f, "(CHARACTER %s%s\n", glyph_ids[i].c_str(), glyph_comments[i].c_str()); // unparse settings into DVI commands sa.clear(); push_stack.clear(); CharstringBounds boundser(font_xform); int program_number = mapped_font0; const CharstringProgram *program = finfo.program(); for (const Setting *s = settings.begin(); s < settings.end(); s++) switch (s->op) { case Setting::SHOW: if (vpl || program == finfo.program()) boundser.char_bounds(program->glyph_context(s->y)); // 3.Aug.2004 -- reported by Marco Kuhlmann: Don't use // glyph_ids[] array when looking at a different font. if (program_number == 0) sa << " (SETCHAR " << glyph_ids[s->x] << ')' << glyph_base_comments[s->x] << "\n"; else sa << " (SETCHAR D " << s->x << ")\n"; break; case Setting::MOVE: { int x = 0, y = 0; while (s+1 < settings.end() && s[1].op == Setting::MOVE) x += s->x, y += s->y, s++; if (vpl) boundser.translate(s->x + x, s->y + y); if (s->x + x) sa << " (MOVERIGHT R " << pr.render(s->x + x) << ")\n"; if (s->y + y) sa << " (MOVEUP R " << pr.render(s->y + y) << ")\n"; break; } case Setting::RULE: if (vpl) { boundser.mark(Point(0, 0)); boundser.mark(Point(s->x, s->y)); boundser.translate(s->x, 0); } sa << " (SETRULE R " << pr.render(s->y) << " R " << pr.render(s->x) << ")\n"; break; case Setting::FONT: if ((int) s->x != program_number) { program = metrics.mapped_font((int) s->x); program_number = (int) s->x; sa << " (SELECTFONT D " << font_mapping[program_number] << ")\n"; } break; case Setting::PUSH: push_stack.push_back(boundser.transform(Point(0, 0))); sa << " (PUSH)\n"; break; case Setting::POP: { assert(push_stack.size()); Point p = push_stack.back() - boundser.transform(Point(0, 0)); if (vpl) boundser.translate(p.x, p.y); push_stack.pop_back(); sa << " (POP)\n"; break; } case Setting::SPECIAL: { bool needhex = false; for (const char *str = s->s.begin(); str < s->s.end() && !needhex; str++) if (*str < ' ' || *str > '~' || *str == '(' || *str == ')') needhex = true; if (needhex) { sa << " (SPECIALHEX "; for (const char *str = s->s.begin(); str < s->s.end(); str++) { static const char hexdig[] = "0123456789ABCDEF"; int val = (unsigned char) *str; sa << hexdig[val >> 4] << hexdig[val & 0xF]; } sa << ")\n"; } else sa << " (SPECIAL " << s->s << ")\n"; break; } } assert(push_stack.size() == 0); // output information boundser.output(bounds, width); pr.print(" (CHARWD", width); if (bounds[3] > 0) pr.print(" (CHARHT", bounds[3]); if (bounds[1] < 0) pr.print(" (CHARDP", -bounds[1]); if (bounds[2] > width) pr.print_transformed(" (CHARIC", pr.transform(bounds[2]) - pr.transform(width)); if (vpl && (settings.size() > 1 || settings[0].op != Setting::SHOW)) fprintf(f, " (MAP\n%s )\n", sa.c_str()); fprintf(f, " )\n"); } // at last, close the file fclose(f); // Did we print a number too big for TeX to handle? If so, try again. if (max_printed_real >= 2047) { if (metrics.design_units() <= 1) errh->fatal("This font appears to be broken. It has characters so big that the PL format\ncannot represent them."); metrics.set_design_units(metrics.design_units() > 200 ? metrics.design_units() - 250 : 1); if (verbose) errh->message("the font%,s metrics overflow the limits of PL files\n(reducing DESIGNUNITS to %d and trying again)", metrics.design_units()); output_pl(metrics, ps_name, boundary_char, finfo, vpl, filename, errh); } } struct Lookup { bool used; bool required; Vector features; GlyphFilter* filter; Lookup() : used(false), required(false), filter(0) { } }; static void find_lookups(const OpenType::ScriptList& scripts, const OpenType::FeatureList& features, Vector& lookups, ErrorHandler* errh) { Vector fids, lookupids; int required; // go over all scripts for (int i = 0; i < interesting_scripts.size(); i += 2) { OpenType::Tag script = interesting_scripts[i]; OpenType::Tag langsys = interesting_scripts[i+1]; // collect features applying to this script scripts.features(script, langsys, required, fids, errh); // only use the selected features features.filter(fids, interesting_features); // mark features as having been used for (int j = (required < 0 ? 0 : -1); j < fids.size(); j++) { int fid = (j < 0 ? required : fids[j]); OpenType::Tag ftag = features.tag(fid); if (features.lookups(fid, lookupids, errh) < 0) lookupids.clear(); for (int k = 0; k < lookupids.size(); k++) { int l = lookupids[k]; if (l < 0 || l >= lookups.size()) errh->error("lookup for %<%s%> feature out of range", OpenType::Tag::langsys_text(script, langsys).c_str()); else { lookups[l].used = true; lookups[l].features.push_back(ftag); if (j < 0) lookups[l].required = true; } } } } // now check for compatible glyph filters for (Lookup* l = lookups.begin(); l < lookups.end(); l++) if (l->used && !l->required) { l->filter = feature_filters[l->features[0]]; for (OpenType::Tag* ft = l->features.begin() + 1; ft < l->features.end(); ft++) if (!l->filter->check_eq(*feature_filters[*ft])) { errh->error("%<%s%> and %<%s%> features share a lookup, but have different filters", l->features[0].text().c_str(), ft->text().c_str()); break; } } } static int write_encoding_file(String &filename, const String &encoding_name, StringAccum &contents, ErrorHandler *errh) { FILE *f; int ok_retval = (access(filename.c_str(), R_OK) >= 0 ? 0 : 1); if (no_create) { errh->message((ok_retval ? "would create encoding file %s" : "would update encoding file %s"), filename.c_str()); return ok_retval; } else if (verbose) errh->message((ok_retval ? "creating encoding file %s" : "updating encoding file %s"), filename.c_str()); int fd = open(filename.c_str(), O_RDWR | O_CREAT, 0666); if (fd < 0) return errh->error("%s: %s", filename.c_str(), strerror(errno)); f = fdopen(fd, "r+"); // NB: also change update_autofont_map if you change this code #if defined(F_SETLKW) && defined(HAVE_FTRUNCATE) { struct flock lock; lock.l_type = F_WRLCK; lock.l_whence = SEEK_SET; lock.l_start = 0; lock.l_len = 0; int result; while ((result = fcntl(fd, F_SETLKW, &lock)) < 0 && errno == EINTR) /* try again */; if (result < 0) { result = errno; fclose(f); return errh->error("locking %s: %s", filename.c_str(), strerror(result)); } } #endif // read old data from encoding file StringAccum sa; int amt; do { if (char *x = sa.reserve(8192)) { amt = fread(x, 1, 8192, f); sa.adjust_length(amt); } else amt = 0; } while (amt != 0); if (!feof(f) || ferror(f)) return errh->error("%s: %s", filename.c_str(), strerror(errno)); String old_encodings = sa.take_string(); bool created = (!old_encodings); // append old encodings int pos1 = old_encodings.find_left("\n%%"); while (pos1 >= 0 && pos1 < old_encodings.length()) { int pos2 = old_encodings.find_left("\n%%", pos1 + 1); if (pos2 < 0) pos2 = old_encodings.length(); if (old_encodings.substring(pos1 + 3, encoding_name.length()) == encoding_name) { // encoding already exists, don't change it fclose(f); if (verbose) errh->message("%s unchanged", filename.c_str()); return 0; } else contents << old_encodings.substring(pos1, pos2 - pos1); pos1 = pos2; } // rewind file #ifdef HAVE_FTRUNCATE rewind(f); if (ftruncate(fd, 0) < 0) #endif { fclose(f); f = fopen(filename.c_str(), "w"); fd = fileno(f); } ignore_result(fwrite(contents.data(), 1, contents.length(), f)); fclose(f); // inform about the new file if necessary if (created) update_odir(O_ENCODING, filename, errh); return 0; } static bool output_encoding(const Metrics &metrics, const Vector &glyph_names, ErrorHandler *errh) { static const char * const hex_digits = "0123456789ABCDEF"; // collect encoding data Vector glyphs; if (!metrics.base_glyphs(glyphs, 256)) return false; StringAccum sa; for (int i = 0; i < 256; i++) { if ((i & 0xF) == 0) sa << (i ? "\n%" : "%") << hex_digits[(i >> 4) & 0xF] << '0' << '\n' << ' '; else if ((i & 0x7) == 0) sa << '\n' << ' '; int g = glyphs[i]; if (g > 0 && g < glyph_names.size()) sa << ' ' << '/' << glyph_names[g]; else sa << " /.notdef"; } sa << '\n'; // digest encoding data MD5_CONTEXT md5; md5_init(&md5); md5_update(&md5, (const unsigned char *)sa.data(), sa.length()); char text_digest[MD5_TEXT_DIGEST_SIZE + 1]; md5_final_text(text_digest, &md5); // name encoding using digest out_encoding_name = "AutoEnc_" + String(text_digest); // create encoding filename bool output_encoding_only = (bool) out_encoding_file; if (!out_encoding_file) out_encoding_file = getodir(O_ENCODING, errh) + String("/a_") + String(text_digest).substring(0, 6) + ".enc"; // exit if we're not responsible for generating an encoding if (!(output_flags & G_ENCODING)) return true; // put encoding block in a StringAccum // 3.Jun.2003: stick command line definition at the end of the encoding, // where it won't confuse idiotic ps2pk StringAccum contents; if (!output_encoding_only) contents << "% THIS FILE WAS AUTOMATICALLY GENERATED -- DO NOT EDIT\n\n\ %%" << out_encoding_name << "\n"; contents << "% Encoding created by otftotfm" << current_time << "\n\ % Command line follows encoding\n"; // the encoding itself contents << '/' << out_encoding_name << " [\n" << sa << "] def\n"; // write banner -- unfortunately this takes some doing String banner = String("Command line: '") + String(invocation.data(), invocation.length()) + String("'"); char *buf = banner.mutable_data(); // get rid of crap characters for (int i = 0; i < banner.length(); i++) if (buf[i] < ' ' || buf[i] > 0176) { if (buf[i] == '\n' || buf[i] == '\r') buf[i] = ' '; else buf[i] = '.'; } // break lines at 80 characters -- it would be nice if this were in a // library while (banner.length() > 0) { int pos = banner.find_left(' '), last_pos = pos; while (pos < 75 && pos >= 0) { last_pos = pos; pos = banner.find_left(' ', pos + 1); } if (last_pos < 0 || (pos < 0 && banner.length() < 75)) last_pos = banner.length(); contents << "% " << banner.substring(0, last_pos) << '\n'; banner = banner.substring(last_pos + 1); } // open encoding file if (out_encoding_file == "-") ignore_result(fwrite(contents.data(), 1, contents.length(), stdout)); else if (write_encoding_file(out_encoding_file, out_encoding_name, contents, errh) == 1) update_odir(O_ENCODING, out_encoding_file, errh); return true; } static void output_tfm(Metrics &metrics, const String &ps_name, int boundary_char, const FontInfo &finfo, String tfm_filename, String vf_filename, String pl_filename, ErrorHandler *errh) { bool had_pl_filename = !pl_filename.empty(); bool vpl = vf_filename; if (!pl_filename) { if (no_create) { errh->message("would write %s to temporary file", (vpl ? "VPL" : "PL")); pl_filename = ""; } else { int pl_fd = temporary_file(pl_filename, errh); if (pl_fd < 0) return; output_pl(metrics, ps_name, boundary_char, finfo, vpl, pl_filename, errh); close(pl_fd); } } StringAccum command; if (vpl) command << "vptovf " << shell_quote(pl_filename) << ' ' << shell_quote(vf_filename) << ' ' << shell_quote(tfm_filename) << " 2>&1"; else command << "pltotf " << shell_quote(pl_filename) << ' ' << shell_quote(tfm_filename) << " 2>&1"; FILE* cmdfile = mypopen(command.c_str(), "r", errh); int status; if (cmdfile) { StringAccum results; while (!feof(cmdfile)) { char* buf = results.reserve(BUFSIZ); results.adjust_length(fread(buf, 1, BUFSIZ, cmdfile)); } // compensate for shitty vptovf/pltotf messages char* by_units, *last_line; while (!results.empty() && (by_units = strstr((char*) results.c_str(), " units")) && (last_line = strrchr((char*) results.c_str(), '\n')) && results.end() - last_line > 1 && isdigit((unsigned char) last_line[1])) { char* start_number = last_line + 1; char* end_number = last_line + 2; while (end_number < results.end() && isdigit((unsigned char) *end_number)) ++end_number; if (end_number < results.end() && *end_number == '.') { char* dot = end_number; ++end_number; while (end_number < results.end() && end_number < dot + 8 && isdigit((unsigned char) *end_number)) ++end_number; } String number(start_number, end_number); char* by_units_dest = by_units + 1 + (end_number - start_number); memmove(by_units_dest, by_units + 1, start_number - (by_units + 1)); memmove(by_units + 1, number.begin(), number.length()); } if (!results.empty()) fwrite(results.begin(), 1, results.length(), stderr); status = pclose(cmdfile); } else status = -1; if (!no_create && !had_pl_filename) unlink(pl_filename.c_str()); if (status != 0) errh->fatal("%s execution failed", (vpl ? "vptovf" : "pltotf")); else { update_odir(O_TFM, tfm_filename, errh); if (vpl) update_odir(O_VF, vf_filename, errh); } } void output_metrics(Metrics &metrics, const String &ps_name, int boundary_char, const FontInfo &finfo, const String &encoding_name, const String &encoding_file, const String &font_name, String (*dvips_include)(const String &ps_name, const FontInfo &, ErrorHandler *), ErrorHandler *errh) { String base_font_name = font_name; bool need_virtual = metrics.need_virtual(257); if (need_virtual) { if (output_flags & G_VMETRICS) base_font_name = make_base_font_name(font_name); else if (output_flags & G_METRICS) errh->warning("features require virtual fonts"); } // output virtual metrics if (!(output_flags & G_VMETRICS)) /* do nothing */; else if (!need_virtual) { if (automatic) { // erase old virtual font String vf = getodir(O_VF, errh) + "/" + font_name + ".vf"; if (no_create) errh->message("would remove potential VF file %<%s%>", vf.c_str()); else { if (verbose) errh->message("removing potential VF file %<%s%>", vf.c_str()); if (unlink(vf.c_str()) < 0 && errno != ENOENT) errh->error("removing %s: %s", vf.c_str(), strerror(errno)); } } } else { String vplfile; if (output_flags & G_ASCII) { vplfile = getodir(O_VPL, errh) + "/" + font_name + ".vpl"; output_pl(metrics, ps_name, boundary_char, finfo, true, vplfile, errh); update_odir(O_VPL, vplfile, errh); } if (output_flags & G_BINARY) { String tfm = getodir(O_TFM, errh) + "/" + font_name + ".tfm"; String vf = getodir(O_VF, errh) + "/" + font_name + ".vf"; output_tfm(metrics, ps_name, boundary_char, finfo, tfm, vf, vplfile, errh); } } // quit if no base needed metrics.make_base(257); if (!metrics.need_base()) return; // output metrics double save_minimum_kern = minimum_kern; if (need_virtual) minimum_kern = 100000; if (output_flags & G_METRICS) { String plfile; if (output_flags & G_ASCII) { plfile = getodir(O_PL, errh) + "/" + base_font_name + ".pl"; output_pl(metrics, ps_name, boundary_char, finfo, false, plfile, errh); update_odir(O_PL, plfile, errh); } if (output_flags & G_BINARY) { String tfm = getodir(O_TFM, errh) + "/" + base_font_name + ".tfm"; output_tfm(metrics, ps_name, boundary_char, finfo, tfm, String(), plfile, errh); } } minimum_kern = save_minimum_kern; // print DVIPS map line if (errh->nerrors() == 0 && (output_flags & G_PSFONTSMAP)) { StringAccum sa; sa << base_font_name << ' ' << ps_name << " \""; if (extend) sa << extend << " ExtendFont "; if (slant) sa << slant << " SlantFont "; if (encoding_name) sa << encoding_name << " ReEncodeFont\" <[" << pathname_filename(encoding_file); else sa << "\""; sa << ' ' << dvips_include(ps_name, finfo, errh) << '\n'; update_autofont_map(base_font_name, sa.take_string(), errh); // if virtual font, remove any map line for base font name if (base_font_name != font_name) update_autofont_map(font_name, "", errh); } } enum { F_GSUB_TRY = 1, F_GSUB_PART = 2, F_GSUB_ALL = 4, F_GPOS_TRY = 8, F_GPOS_PART = 16, F_GPOS_ALL = 32, X_UNUSED = 0, X_BOTH_NONE = 1, X_GSUB_NONE = 2, X_GSUB_PART = 3, X_GPOS_NONE = 4, X_GPOS_PART = 5, X_COUNT }; static const char * const x_messages[] = { "% ignored, not supported by font", "% ignored, too complex for me", "complex substitutions from % ignored", "some complex substitutions from % ignored", "complex positionings from % ignored", "some complex positionings from % ignored", }; static void report_underused_features(const HashMap &feature_usage, ErrorHandler *errh) { Vector x[X_COUNT]; for (int i = 0; i < interesting_features.size(); i++) { OpenType::Tag f = interesting_features[i]; int fu = feature_usage[f.value()]; String ftext = errh->format("%<%s%>", f.text().c_str()); if (fu == 0) x[X_UNUSED].push_back(ftext); else if ((fu & (F_GSUB_TRY | F_GPOS_TRY)) == fu) x[X_BOTH_NONE].push_back(ftext); else { if (fu & F_GSUB_TRY) { if ((fu & (F_GSUB_PART | F_GSUB_ALL)) == 0) x[X_GSUB_NONE].push_back(ftext); else if (fu & F_GSUB_PART) x[X_GSUB_PART].push_back(ftext); } if (fu & F_GPOS_TRY) { if ((fu & (F_GPOS_PART | F_GPOS_ALL)) == 0) x[X_GPOS_NONE].push_back(ftext); else if (fu & F_GPOS_PART) x[X_GPOS_PART].push_back(ftext); } } } for (int i = 0; i < X_COUNT; i++) if (x[i].size()) goto found; return; found: for (int i = 0; i < X_COUNT; i++) if (x[i].size()) { StringAccum sa; const char* msg_pct = strchr(x_messages[i], '%'); sa.append(x_messages[i], msg_pct - x_messages[i]); const char* sep = (x[i].size() > 2 ? ", " : " "); for (const String* a = x[i].begin(); a < x[i].end() - 1; a++) sa << *a << sep; sa << (x[i].size() > 1 ? "and " : "") << x[i].back() << (x[i].size() > 1 ? " features" : " feature") << (msg_pct+1); sa.append_break_lines(sa.take_string(), 58); errh->warning("%s", sa.c_str()); } } static String otf_filename; static String main_dvips_map(const String &ps_name, const FontInfo &finfo, ErrorHandler *errh) { if (String fn = installed_type1(otf_filename, ps_name, (output_flags & G_TYPE1) != 0, errh)) return "<" + pathname_filename(fn); if (!finfo.cff) { String ttf_fn, t42_fn; ttf_fn = installed_truetype(otf_filename, (output_flags & G_TRUETYPE) != 0, errh); t42_fn = installed_type42(otf_filename, ps_name, (output_flags & G_TYPE42) != 0, errh); if (t42_fn && (!ttf_fn || (output_flags & G_TYPE42) != 0)) return "<" + pathname_filename(t42_fn); else if (ttf_fn) return "<" + pathname_filename(ttf_fn); } return "<" + pathname_filename(otf_filename); } static void do_gsub(Metrics& metrics, const OpenType::Font& otf, DvipsEncoding& dvipsenc, bool dvipsenc_literal, HashMap& feature_usage, const Vector& glyph_names, ErrorHandler* errh) { // find activated GSUB features OpenType::Gsub gsub(otf.table("GSUB"), &otf, errh); Vector lookups(gsub.nlookups(), Lookup()); find_lookups(gsub.script_list(), gsub.feature_list(), lookups, errh); // find all characters that might result Vector used(glyph_names.size(), false); for (Metrics::Code c = 0; c < metrics.encoding_size(); ++c) { Metrics::Glyph g = metrics.glyph(c); if (g >= 0 && g < used.size()) used[g] = true; } for (int i = 0; i < lookups.size(); ++i) if (lookups[i].used) { OpenType::GsubLookup l = gsub.lookup(i); l.mark_out_glyphs(gsub, used); } OpenType::Coverage used_coverage(used); // apply activated GSUB features Vector subs; for (int i = 0; i < lookups.size(); i++) if (lookups[i].used) { OpenType::GsubLookup l = gsub.lookup(i); subs.clear(); bool understood = l.unparse_automatics(gsub, subs, used_coverage); // check for -ffina, which should apply only at the ends of words, // and -finit, which should apply only at the beginnings. OpenType::Tag feature = (lookups[i].features.size() == 1 ? lookups[i].features[0] : OpenType::Tag()); if (feature == OpenType::Tag("fina") || feature == OpenType::Tag("fin2") || feature == OpenType::Tag("fin3")) { if (dvipsenc.boundary_char() < 0) errh->warning("%<-ffina%> requires a boundary character\n(The input encoding didn%,t specify a boundary character, but\nI need one to implement %<-ffina%> features correctly. Try\nthe %<--boundary-char%> option.)"); else { int bg = metrics.boundary_glyph(); for (int j = 0; j < subs.size(); j++) subs[j].add_outer_right(bg); } } else if (feature == OpenType::Tag("init")) { int bg = metrics.boundary_glyph(); for (int j = 0; j < subs.size(); j++) subs[j].add_outer_left(bg); } //for (int subno = 0; subno < subs.size(); subno++) fprintf(stderr, "%5d\t%s\n", i, subs[subno].unparse().c_str()); // figure out which glyph filter to use int nunderstood = metrics.apply(subs, !dvipsenc_literal, i, *lookups[i].filter, glyph_names); // mark as used int d = (understood && nunderstood == subs.size() ? F_GSUB_ALL : (nunderstood ? F_GSUB_PART : 0)) + F_GSUB_TRY; for (int j = 0; j < lookups[i].features.size(); j++) feature_usage.find_force(lookups[i].features[j].value()) |= d; } // apply alternate selectors if (metrics.altselectors() && !dvipsenc_literal) { // do lookups altselector_features.swap(interesting_features); altselector_feature_filters.swap(feature_filters); Vector alt_lookups(gsub.nlookups(), Lookup()); find_lookups(gsub.script_list(), gsub.feature_list(), alt_lookups, ErrorHandler::silent_handler()); Vector alt_subs; for (int i = 0; i < alt_lookups.size(); i++) if (alt_lookups[i].used) { OpenType::GsubLookup l = gsub.lookup(i); alt_subs.clear(); (void) l.unparse_automatics(gsub, alt_subs, used_coverage); metrics.apply_alternates(alt_subs, i, *alt_lookups[i].filter, glyph_names); } altselector_features.swap(interesting_features); altselector_feature_filters.swap(feature_filters); } } static bool kern_feature_requested() { return std::find(interesting_features.begin(), interesting_features.end(), OpenType::Tag("kern")) != interesting_features.end(); } static void do_try_ttf_kern(Metrics& metrics, const OpenType::Font& otf, HashMap& feature_usage, ErrorHandler* errh) { // if no GPOS "kern" lookups and "kern" requested, try "kern" table if (!kern_feature_requested()) return; try { OpenType::KernTable kern(otf.table("kern"), errh); Vector poss; bool understood = kern.unparse_automatics(poss, errh); int nunderstood = metrics.apply(poss); // mark as used int d = (understood && nunderstood == poss.size() ? F_GPOS_ALL : (nunderstood ? F_GPOS_PART : 0)) + F_GPOS_TRY; feature_usage.find_force(OpenType::Tag("kern").value()) |= d; } catch (OpenType::BlankTable) { // nada } catch (OpenType::Error e) { errh->warning("kern %<%s%> error, continuing", e.description.c_str()); } } static void do_gpos(Metrics& metrics, const OpenType::Font& otf, HashMap& feature_usage, ErrorHandler* errh) { OpenType::Gpos gpos(otf.table("GPOS"), errh); Vector lookups(gpos.nlookups(), Lookup()); find_lookups(gpos.script_list(), gpos.feature_list(), lookups, errh); // OpenType recommends that if GPOS exists, but the "kern" feature loads // no lookups, we use the TrueType "kern" table, if any. if (kern_feature_requested()) { OpenType::Tag kern_tag("kern"); for (Lookup *l = lookups.begin(); l != lookups.end(); ++l) if (std::find(l->features.begin(), l->features.end(), kern_tag) != l->features.end()) goto skip_ttf_kern; do_try_ttf_kern(metrics, otf, feature_usage, errh); skip_ttf_kern: ; } Vector poss; for (int i = 0; i < lookups.size(); i++) if (lookups[i].used) { OpenType::GposLookup l = gpos.lookup(i); poss.clear(); bool understood = l.unparse_automatics(poss, errh); int nunderstood = metrics.apply(poss); // mark as used int d = (understood && nunderstood == poss.size() ? F_GPOS_ALL : (nunderstood ? F_GPOS_PART : 0)) + F_GPOS_TRY; for (int j = 0; j < lookups[i].features.size(); j++) feature_usage.find_force(lookups[i].features[j].value()) |= d; } } static void do_math_spacing(Metrics &metrics, const FontInfo &finfo, const DvipsEncoding &dvipsenc) { Transform font_xform; if (extend) font_xform.scale(extend, 1); if (slant) font_xform.shear(slant); CharstringBounds boundser(font_xform); double x_height = finfo.x_height(font_xform); double actual_slant = font_slant(finfo); int boundary_char = dvipsenc.boundary_char(); double bounds[4], width; for (int code = 0; code < metrics.encoding_size(); code++) if (metrics.was_base_glyph(code) && code != boundary_char && char_bounds(bounds, width, finfo, font_xform, metrics.unicode(code))) { int left_sb = (bounds[0] < 0 ? (int) ceil(-bounds[0]) : 0); metrics.add_single_positioning(code, left_sb, 0, left_sb); if (skew_char >= 0 && code < 256) { double sheight = std::max(bounds[3], x_height) - 0.5 * x_height; double right_sb = std::max(bounds[2] - width, 0.0); double desired = left_sb + 0.5 * width + actual_slant * sheight + 0.25 * right_sb; double computed = 0.5 * (left_sb + width + right_sb); int skew = (int) (desired - computed); metrics.add_kern(code, skew_char, skew); } } } static void do_file(const String &otf_filename, const OpenType::Font &otf, const DvipsEncoding &dvipsenc_in, bool dvipsenc_literal, ErrorHandler *errh) { FontInfo finfo(&otf, errh); if (!finfo.ok()) return; if (!finfo.cff) errh->warning("TrueType-flavored font support is experimental"); if (override_is_fixed_pitch) finfo.set_is_fixed_pitch(is_fixed_pitch); if (override_italic_angle) finfo.set_italic_angle(italic_angle); if (override_x_height != FontInfo::x_height_auto) finfo.set_x_height(override_x_height, x_height); // save glyph names Vector glyph_names; finfo.glyph_names(glyph_names); OpenType::debug_glyph_names = glyph_names; // set typeface name from font family name { String typeface = finfo.family_name(); // make it reasonable for the shell StringAccum sa; for (int i = 0; i < typeface.length(); i++) if (isalnum((unsigned char) typeface[i]) || typeface[i] == '_' || typeface[i] == '-' || typeface[i] == '.' || typeface[i] == ',' || typeface[i] == '+') sa << typeface[i]; set_typeface(sa.length() ? sa.take_string() : font_name, false); } // initialize encoding DvipsEncoding dvipsenc(dvipsenc_in); // make copy Metrics metrics(finfo.program(), finfo.nglyphs()); // encode boundary glyph at 256; pretend its Unicode value is '\n' metrics.encode(256, '\n', metrics.boundary_glyph()); if (dvipsenc_literal) dvipsenc.make_metrics(metrics, finfo, 0, true, errh); else { T1Secondary secondary(finfo, font_name, otf_filename); dvipsenc.make_metrics(metrics, finfo, &secondary, false, errh); } // maintain statistics about features HashMap feature_usage(0); // apply activated GSUB features try { do_gsub(metrics, otf, dvipsenc, dvipsenc_literal, feature_usage, glyph_names, errh); } catch (OpenType::BlankTable) { // nada } catch (OpenType::Error e) { errh->warning("GSUB %<%s%> error, continuing", e.description.c_str()); } // apply LIGKERN ligature commands to the result dvipsenc.apply_ligkern_lig(metrics, errh); // test fake ligature mechanism //metrics.add_threeligature('T', 'h', 'e', '0'); // reencode characters to fit within 8 bytes (+ 1 for the boundary) if (!dvipsenc_literal) metrics.shrink_encoding(257, dvipsenc_in, errh); // apply activated GPOS features try { do_gpos(metrics, otf, feature_usage, errh); } catch (OpenType::BlankTable) { do_try_ttf_kern(metrics, otf, feature_usage, errh); } catch (OpenType::Error e) { errh->warning("GPOS %<%s%> error, continuing", e.description.c_str()); } // apply LIGKERN kerning and POS positioning commands to the result dvipsenc.apply_ligkern_kern(metrics, errh); dvipsenc.apply_position(metrics, errh); // use prespecified raw fonts for (BaseEncoding **be = base_encodings.begin(); be != base_encodings.end(); be++) if (!(*be)->secondary) { Vector mapp; (*be)->encoding.make_base_mappings(mapp, finfo); metrics.apply_base_encoding((*be)->font_name, (*be)->encoding, mapp); } // remove extra characters metrics.cut_encoding(257); //metrics.unparse(); int boundary_char = dvipsenc.boundary_char(); // apply letterspacing, if any if (letterspace) for (int code = 0; code < metrics.encoding_size(); code++) if (metrics.was_base_glyph(code) && code != boundary_char) { metrics.add_single_positioning(code, letterspace / 2, 0, letterspace); if (code < 256) { metrics.add_kern(code, 256, -letterspace / 2); metrics.add_kern(256, code, -letterspace / 2); } } // apply math letterspacing, if any if (math_spacing) do_math_spacing(metrics, finfo, dvipsenc); // reencode right components of boundary_glyph as boundary_char if (metrics.reencode_right_ligkern(256, boundary_char) > 0 && boundary_char < 0) { errh->warning("no boundary character, ignoring some ligatures and/or kerns\n"); errh->message("(You may want to try the --boundary-char option.)"); } // report unused and underused features if any report_underused_features(feature_usage, errh); // figure out our FONTNAME if (!font_name) { // derive font name from OpenType font name font_name = finfo.postscript_name(); if (encoding_file) { int slash = encoding_file.find_right('/') + 1; int dot = encoding_file.find_right('.'); if (dot < slash) // includes dot < 0 case dot = encoding_file.length(); font_name += String("--") + encoding_file.substring(slash, dot - slash); } if (interesting_scripts.size() != 2 || interesting_scripts[0] != OpenType::Tag("latn") || interesting_scripts[1].valid()) for (int i = 0; i < interesting_scripts.size(); i += 2) { font_name += String("--S") + interesting_scripts[i].text(); if (interesting_scripts[i+1].valid()) font_name += String(".") + interesting_scripts[i+1].text(); } for (int i = 0; i < interesting_features.size(); i++) if (feature_usage[interesting_features[i].value()]) font_name += String("--F") + interesting_features[i].text(); } // output encoding if (dvipsenc_literal) { out_encoding_name = dvipsenc_in.name(); out_encoding_file = dvipsenc_in.filename(); } else output_encoding(metrics, glyph_names, errh); // set up coding scheme if (metrics.coding_scheme()) metrics.set_design_units(1); else metrics.set_coding_scheme(out_encoding_name); // force no type 1 if (!finfo.cff && (output_flags & G_TYPE1)) { errh->warning("assuming --no-type1 since this font is TrueType-flavored"); output_flags &= ~G_TYPE1; } // output ::otf_filename = otf_filename; output_metrics(metrics, finfo.postscript_name(), dvipsenc.boundary_char(), finfo, out_encoding_name, out_encoding_file, font_name, main_dvips_map, errh); } String installed_metrics_font_name(const String &base_font_name, const String &secondary) { for (BaseEncoding **be = base_encodings.begin(); be != base_encodings.end(); be++) if ((*be)->secondary == secondary && ::font_name == base_font_name) return (*be)->font_name; return String(); } extern "C" { static int clp_parse_char(Clp_Parser *clp, const char *arg, int complain, void *) { if (arg[0] && !arg[1] && !isdigit((unsigned char) arg[0])) { clp->val.i = (unsigned char)arg[0]; return 1; } else if (arg[0] == '-' || isdigit((unsigned char) arg[0])) { char *end; clp->val.i = strtol(arg, &end, 10); if (clp->val.i <= 255 && !*end) return 1; } if (complain) Clp_OptionError(clp, "'%O' expects a character, not '%s'", arg); return 0; } } static void parse_base_encodings(const String &filename, ErrorHandler *errh) { String str = read_file(filename, errh, true); String print_filename = (filename == "-" ? "" : filename) + ":"; int lineno = 1; str.c_str(); const char *s_end = str.end(); for (const char *s = str.begin(); s != s_end; ) { while (s != s_end && isspace((unsigned char) *s) && *s != '\n' && *s != '\r') s++; // skip comments and blank lines if (s != s_end && *s != '%' && *s != '#' && *s != '\n' && *s != '\r') { const char *w1 = s; while (s != s_end && !isspace((unsigned char) *s)) s++; BaseEncoding *be = new BaseEncoding; be->font_name = str.substring(w1, s); while (s != s_end && isspace((unsigned char) *s) && *s != '\n' && *s != '\r') s++; const char *w2 = s; while (s != s_end && !isspace((unsigned char) *s)) s++; String efile = str.substring(w2, s); while (s != s_end && isspace((unsigned char) *s) && *s != '\n' && *s != '\r') s++; if (s != s_end && !isspace((unsigned char) *s) && *s != '%' && *s != '#') { const char *w3 = s; while (s != s_end && !isspace((unsigned char) *s)) s++; be->secondary = str.substring(w3, s); } LandmarkErrorHandler lerrh(errh, print_filename + String(lineno)); int before = lerrh.nerrors(); if (be->secondary) /* encoding ignored */; else if (!efile) lerrh.error("missing encoding name"); else if (String path = locate_encoding(efile, errh)) be->encoding.parse(path, true, true, &lerrh); else lerrh.error("encoding %<%s%> not found", efile.c_str()); if (lerrh.nerrors() == before) base_encodings.push_back(be); else delete be; } while (s != s_end && *s != '\n' && *s != '\r') s++; if (s != s_end && *s == '\r') s++; if (s != s_end && *s == '\n') s++; lineno++; } } int main(int argc, char *argv[]) { #ifndef WIN32 handle_sigchld(); #endif Clp_Parser *clp = Clp_NewParser(argc, (const char * const *)argv, sizeof(options) / sizeof(options[0]), options); Clp_AddType(clp, CHAR_OPTTYPE, 0, clp_parse_char, 0); program_name = Clp_ProgramName(clp); #if HAVE_KPATHSEA kpsei_init(argv[0], "lcdftools"); #endif #ifdef HAVE_CTIME { time_t t = time(0); char *c = ctime(&t); current_time = " on " + String(c).substring(0, -1); // get rid of \n } #endif for (int i = 0; i < argc; i++) invocation << (i ? " " : "") << argv[i]; ErrorHandler *errh = ErrorHandler::static_initialize(new FileErrorHandler(stderr, String(program_name) + ": ")); const char *input_file = 0; Vector glyphlist_files; bool literal_encoding = false; bool have_encoding_file = false; Vector ligkern; Vector pos; Vector unicoding; Vector base_encoding_files; bool no_ecommand = false, default_ligkern = true; int warn_missing = -1; unsigned specified_output_flags = 0; String codingscheme; const char* odirs[NUMODIR + 1]; for (int i = 0; i <= NUMODIR; ++i) { odirs[i] = 0; } GlyphFilter current_substitution_filter; GlyphFilter current_alternate_filter; GlyphFilter* current_filter_ptr = &null_filter; Vector allocated_filters; while (1) { int opt = Clp_Next(clp); switch (opt) { case SCRIPT_OPT: { String arg = clp->vstr; int period = arg.find_left('.'); OpenType::Tag scr(period <= 0 ? arg : arg.substring(0, period)); if (scr.valid() && period > 0) { OpenType::Tag lang(arg.substring(period + 1)); if (lang.valid()) { interesting_scripts.push_back(scr); interesting_scripts.push_back(lang); } else usage_error(errh, "bad language tag"); } else if (scr.valid()) { interesting_scripts.push_back(scr); interesting_scripts.push_back(OpenType::Tag()); } else usage_error(errh, "bad script tag"); break; } case FEATURE_OPT: { OpenType::Tag t(clp->vstr); if (!t.valid()) usage_error(errh, "bad feature tag"); else if (feature_filters[t]) usage_error(errh, "feature %<%s%> included twice", t.text().c_str()); else { if (!current_filter_ptr) { current_filter_ptr = new GlyphFilter(current_substitution_filter + current_alternate_filter); allocated_filters.push_back(current_filter_ptr); } interesting_features.push_back(t); feature_filters.insert(t, current_filter_ptr); } break; } case LETTER_FEATURE_OPT: { OpenType::Tag t(clp->vstr); if (!t.valid()) usage_error(errh, "bad feature tag"); else if (feature_filters[t]) usage_error(errh, "feature %<%s%> included twice", t.text().c_str()); else { interesting_features.push_back(t); GlyphFilter* gf = new GlyphFilter; gf->add_substitution_filter("", false, errh); *gf += current_alternate_filter; feature_filters.insert(t, gf); } break; } case SUBS_FILTER_OPT: current_substitution_filter = null_filter; /* fallthru */ case EXCLUDE_SUBS_OPT: case INCLUDE_SUBS_OPT: current_substitution_filter.add_substitution_filter(clp->vstr, opt == EXCLUDE_SUBS_OPT, errh); current_filter_ptr = 0; break; case CLEAR_SUBS_OPT: current_substitution_filter = null_filter; current_filter_ptr = 0; break; case ENCODING_OPT: if (encoding_file) usage_error(errh, "encoding specified twice"); encoding_file = clp->vstr; have_encoding_file = true; break; case LITERAL_ENCODING_OPT: if (encoding_file) usage_error(errh, "encoding specified twice"); encoding_file = clp->vstr; have_encoding_file = true; literal_encoding = true; break; case BASE_ENCODINGS_OPT: base_encoding_files.push_back(clp->vstr); break; case EXTEND_OPT: if (extend) usage_error(errh, "extend value specified twice"); extend = clp->val.d; break; case SLANT_OPT: if (slant) usage_error(errh, "slant value specified twice"); slant = clp->val.d; break; case LETTERSPACE_OPT: if (letterspace) usage_error(errh, "letterspacing value specified twice"); letterspace = clp->val.i; break; case SPACE_FACTOR_OPT: if (space_factor != 1) usage_error(errh, "space factor specified twice"); space_factor = clp->val.d; break; case MATH_SPACING_OPT: math_spacing = !clp->negated; if (math_spacing && clp->have_val) { if (clp->val.i < 0 || clp->val.i > 255) usage_error(errh, "--math-spacing skew character must be between 0 and 255"); skew_char = clp->val.i; } break; case DESIGN_SIZE_OPT: if (design_size > 0) usage_error(errh, "design size value specified twice"); else if (clp->val.d <= 0) usage_error(errh, "design size must be > 0"); design_size = clp->val.d; break; case LIGKERN_OPT: ligkern.push_back(clp->vstr); break; case POSITION_OPT: pos.push_back(clp->vstr); break; case WARN_MISSING_OPT: warn_missing = !clp->negated; break; case NO_ECOMMAND_OPT: no_ecommand = true; break; case DEFAULT_LIGKERN_OPT: default_ligkern = !clp->negated; break; case BOUNDARY_CHAR_OPT: ligkern.push_back(String("|| = ") + String(clp->val.i)); break; case ALTSELECTOR_CHAR_OPT: ligkern.push_back(String("^^ = ") + String(clp->val.i)); break; case ALTSELECTOR_FEATURE_OPT: { OpenType::Tag t(clp->vstr); if (!t.valid()) usage_error(errh, "bad feature tag"); else if (altselector_feature_filters[t]) usage_error(errh, "altselector feature %<%s%> included twice", t.text().c_str()); else { if (!current_filter_ptr) { current_filter_ptr = new GlyphFilter(current_substitution_filter + current_alternate_filter); allocated_filters.push_back(current_filter_ptr); } altselector_features.push_back(t); altselector_feature_filters.insert(t, current_filter_ptr); } break; } case ALTERNATES_FILTER_OPT: current_alternate_filter = null_filter; /* fallthru */ case EXCLUDE_ALTERNATES_OPT: case INCLUDE_ALTERNATES_OPT: current_alternate_filter.add_alternate_filter(clp->vstr, opt == EXCLUDE_ALTERNATES_OPT, errh); current_filter_ptr = 0; break; case CLEAR_ALTERNATES_OPT: current_alternate_filter = null_filter; current_filter_ptr = 0; break; case UNICODING_OPT: unicoding.push_back(clp->vstr); break; case CODINGSCHEME_OPT: if (codingscheme) usage_error(errh, "coding scheme specified twice"); codingscheme = clp->vstr; if (codingscheme.length() > 39) errh->warning("only first 39 characters of coding scheme are significant"); if (codingscheme.find_left('(') >= 0 || codingscheme.find_left(')') >= 0) usage_error(errh, "coding scheme cannot contain parentheses"); break; case AUTOMATIC_OPT: automatic = !clp->negated; break; case VENDOR_OPT: if (!set_vendor(clp->vstr)) usage_error(errh, "vendor name specified twice"); break; case TYPEFACE_OPT: if (!set_typeface(clp->vstr, true)) usage_error(errh, "typeface name specified twice"); break; case VIRTUAL_OPT: if (clp->negated) output_flags &= ~G_VMETRICS; else output_flags |= G_VMETRICS; specified_output_flags |= G_VMETRICS; break; case NO_ENCODING_OPT: case NO_TYPE1_OPT: case NO_DOTLESSJ_OPT: case NO_UPDMAP_OPT: case UPDMAP_SYS_OPT: output_flags &= ~(opt - NO_OUTPUT_OPTS); specified_output_flags |= opt - NO_OUTPUT_OPTS; break; case TRUETYPE_OPT: case TYPE42_OPT: case UPDMAP_USER_OPT: if (!clp->negated) output_flags |= (opt - YES_OUTPUT_OPTS); else output_flags &= ~(opt - YES_OUTPUT_OPTS); specified_output_flags |= opt - YES_OUTPUT_OPTS; break; case OUTPUT_ENCODING_OPT: if (out_encoding_file) usage_error(errh, "encoding output file specified twice"); out_encoding_file = (clp->have_val ? clp->vstr : "-"); output_flags = G_ENCODING; specified_output_flags = -1; break; case MINIMUM_KERN_OPT: minimum_kern = clp->val.d; break; case MAP_FILE_OPT: if (clp->negated) output_flags &= ~G_PSFONTSMAP; else { output_flags |= G_PSFONTSMAP; if (!set_map_file(clp->vstr)) usage_error(errh, "map file specified twice"); } specified_output_flags |= G_PSFONTSMAP; break; case PL_OPT: if (clp->negated) output_flags &= ~G_ASCII; else output_flags |= G_ASCII; specified_output_flags |= G_ASCII; break; case TFM_OPT: if (clp->negated) output_flags &= ~G_BINARY; else output_flags |= G_BINARY; specified_output_flags |= G_BINARY; break; case ENCODING_DIR_OPT: case TFM_DIR_OPT: case PL_DIR_OPT: case VF_DIR_OPT: case VPL_DIR_OPT: case TYPE1_DIR_OPT: case TRUETYPE_DIR_OPT: case TYPE42_DIR_OPT: case DIR_OPT: if (!odirs[opt - DIR_OPTS]) odirs[opt - DIR_OPTS] = clp->vstr; else usage_error(errh, "%s directory specified twice", odirname(opt - DIR_OPTS)); break; case FONT_NAME_OPT: font_name: if (font_name) usage_error(errh, "font name specified twice"); font_name = clp->vstr; break; case FIXED_PITCH_OPT: override_is_fixed_pitch = true; is_fixed_pitch = !clp->negated; break; case PROPORTIONAL_WIDTH_OPT: override_is_fixed_pitch = true; is_fixed_pitch = !!clp->negated; break; case ITALIC_ANGLE_OPT: override_italic_angle = true; italic_angle = clp->val.d; break; case GLYPHLIST_OPT: glyphlist_files.push_back(clp->vstr); break; case QUERY_FEATURES_OPT: usage_error(errh, "run % instead"); break; case QUERY_SCRIPTS_OPT: usage_error(errh, "run % instead"); break; case QUIET_OPT: if (clp->negated) errh = ErrorHandler::default_handler(); else // 9.Nov.05 -- need a new SilentErrorHandler, because we use // the base SilentErrorHandler elsewhere to ignore errors errh = new SilentErrorHandler; break; case VERBOSE_OPT: verbose = !clp->negated; break; case NOCREATE_OPT: no_create = clp->negated; break; case FORCE_OPT: force = !clp->negated; break; case KPATHSEA_DEBUG_OPT: #if HAVE_KPATHSEA kpsei_set_debug_flags(clp->val.u); #else errh->warning("Not compiled with kpathsea!"); #endif break; case X_HEIGHT_OPT: { char* ends; if (strcmp(clp->vstr, "auto") == 0) override_x_height = FontInfo::x_height_auto; else if (strcmp(clp->vstr, "x") == 0) override_x_height = FontInfo::x_height_x; else if (strcmp(clp->vstr, "font") == 0 || strcmp(clp->vstr, "os/2") == 0) override_x_height = FontInfo::x_height_os2; else if ((x_height = strtod(clp->vstr, &ends)) >= 0 && *ends == 0 && *clp->vstr != 0) override_x_height = FontInfo::x_height_explicit; else usage_error(errh, "bad --x-height option"); break; } case VERSION_OPT: printf("otftotfm (LCDF typetools) %s\n", VERSION); printf("Copyright (C) 2002-2019 Eddie Kohler\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); exit(0); break; case HELP_OPT: usage(); exit(0); break; case Clp_NotOption: if (input_file && font_name) usage_error(errh, "too many arguments"); else if (input_file) goto font_name; else input_file = clp->vstr; break; case Clp_Done: goto done; case Clp_BadOption: usage_error(errh, 0); break; default: break; } } done: // check for odd option combinations if (warn_missing > 0 && !(output_flags & G_VMETRICS)) errh->warning("%<--warn-missing%> has no effect with %<--no-virtual%>"); if (!(specified_output_flags & (G_BINARY | G_ASCII))) output_flags |= G_BINARY; // set up file names if (!input_file) usage_error(errh, "no font filename provided"); if (encoding_file == "-") encoding_file = ""; // set up output directories if (odirs[NUMODIR]) { for (int i = 0; i < NUMODIR; ++i) if (!odirs[i]) odirs[i] = odirs[NUMODIR]; } for (int i = 0; i < NUMODIR; ++i) if (odirs[i]) setodir(i, odirs[i]); // set up feature filters if (!altselector_features.size()) { if (!current_filter_ptr) { current_filter_ptr = new GlyphFilter(current_substitution_filter + current_alternate_filter); allocated_filters.push_back(current_filter_ptr); } altselector_features.push_back(OpenType::Tag("dlig")); altselector_feature_filters.insert(OpenType::Tag("dlig"), current_filter_ptr); altselector_features.push_back(OpenType::Tag("salt")); altselector_feature_filters.insert(OpenType::Tag("salt"), current_filter_ptr); } else if (!current_filter_ptr) { errh->warning("some filtering options ignored"); errh->message("(--include-*, --exclude-*, and --*-filter options must occur\nbefore the feature options to which they should apply.)"); } try { // read font otf_data = read_file(input_file, errh); if (errh->nerrors()) exit(1); LandmarkErrorHandler cerrh(errh, printable_filename(input_file)); BailErrorHandler bail_errh(&cerrh); OpenType::Font otf(otf_data, &bail_errh); assert(otf.ok()); // figure out scripts we care about if (!interesting_scripts.size()) { interesting_scripts.push_back(Efont::OpenType::Tag("latn")); interesting_scripts.push_back(Efont::OpenType::Tag()); } std::sort(interesting_features.begin(), interesting_features.end()); std::sort(altselector_features.begin(), altselector_features.end()); // find glyphlist if (!glyphlist_files.size()) { #if HAVE_KPATHSEA if (String g = kpsei_find_file("glyphlist.txt", KPSEI_FMT_MAP)) { glyphlist_files.push_back(g); if (verbose) errh->message("glyphlist.txt found with kpathsea at %s", g.c_str()); } else #endif glyphlist_files.push_back(GLYPHLISTDIR "/glyphlist.txt"); #if HAVE_KPATHSEA if (String g = kpsei_find_file("texglyphlist.txt", KPSEI_FMT_MAP)) { glyphlist_files.push_back(g); if (verbose) errh->message("texglyphlist.txt found with kpathsea at %s", g.c_str()); } else #endif glyphlist_files.push_back(GLYPHLISTDIR "/texglyphlist.txt"); } // read glyphlist for (String *g = glyphlist_files.begin(); g < glyphlist_files.end(); g++) if (String s = read_file(*g, errh, true)) DvipsEncoding::add_glyphlist(s); // read base encodings for (String *s = base_encoding_files.begin(); s < base_encoding_files.end(); s++) parse_base_encodings(*s, errh); // read encoding DvipsEncoding dvipsenc; if (encoding_file) { if (String path = locate_encoding(encoding_file, errh)) dvipsenc.parse(path, no_ecommand, no_ecommand, errh); else errh->fatal("encoding %<%s%> not found", encoding_file.c_str()); } else { String cff_data(otf.table("CFF")); if (!cff_data) { errh->error("explicit encoding required for TrueType fonts"); errh->message("(Use %<-e ENCODING%> to choose an encoding. %<-e texnansx%> often works.)"); exit(1); } else if (!have_encoding_file) { errh->warning("no encoding provided"); errh->message("(Use %<-e ENCODING%> to choose an encoding. %<-e texnansx%> often works,\nor say %<-e -%> to turn off this warning.)"); } // use encoding from font Cff cff(cff_data, otf.units_per_em(), &bail_errh); Cff::FontParent *font = cff.font(PermString(), &bail_errh); assert(cff.ok() && font->ok()); if (Type1Encoding *t1e = font->type1_encoding()) { for (int i = 0; i < 256; i++) dvipsenc.encode(i, (*t1e)[i]); } else errh->fatal("font has no encoding, specify one explicitly"); } // apply default ligkern commands if (default_ligkern) dvipsenc.parse_ligkern(default_ligkerns, 0, ErrorHandler::silent_handler()); // apply command-line ligkern commands and coding scheme cerrh.set_landmark("--ligkern command"); for (int i = 0; i < ligkern.size(); i++) dvipsenc.parse_ligkern(ligkern[i], 1, &cerrh); cerrh.set_landmark("--position command"); for (int i = 0; i < pos.size(); i++) dvipsenc.parse_position(pos[i], 1, &cerrh); cerrh.set_landmark("--unicoding command"); for (int i = 0; i < unicoding.size(); i++) dvipsenc.parse_unicoding(unicoding[i], 1, &cerrh); if (codingscheme) dvipsenc.set_coding_scheme(codingscheme); if (warn_missing >= 0) dvipsenc.set_warn_missing(warn_missing); do_file(input_file, otf, dvipsenc, literal_encoding, errh); } catch (OpenType::Error e) { errh->error("unhandled exception %<%s%>", e.description.c_str()); } for (int i = 0; i < allocated_filters.size(); ++i) delete allocated_filters[i]; Clp_DeleteParser(clp); return (errh->nerrors() == 0 ? 0 : 1); } lcdf-typetools-2.108/otftotfm/kpseinterface.h0000664000175000017500000000106312732752520016262 00000000000000#ifndef OTFTOTFM_KPSEINTERFACE_H #define OTFTOTFM_KPSEINTERFACE_H #ifdef __cplusplus extern "C" { #endif void kpsei_init(const char* argv0, const char* progname); extern int kpsei_env_sep_char; char* kpsei_path_expand(const char* path); /* free() result */ enum { KPSEI_FMT_WEB2C, KPSEI_FMT_ENCODING, KPSEI_FMT_TYPE1, KPSEI_FMT_OTHER_TEXT, KPSEI_FMT_MAP, KPSEI_FMT_TRUETYPE, KPSEI_FMT_OPENTYPE, KPSEI_FMT_TYPE42 }; char* kpsei_find_file(const char* name, int format); void kpsei_set_debug_flags(unsigned flags); #ifdef __cplusplus } #endif #endif lcdf-typetools-2.108/otftotfm/Makefile.am0000644000175000017500000000164613423375330015325 00000000000000## Process this file with automake to produce Makefile.in AUTOMAKE_OPTIONS = foreign bin_PROGRAMS = otftotfm man_MANS = otftotfm.1 otftotfm_SOURCES = \ automatic.cc automatic.hh \ dvipsencoding.cc dvipsencoding.hh \ glyphfilter.cc glyphfilter.hh \ metrics.cc metrics.hh \ otftotfm.cc otftotfm.hh \ secondary.cc secondary.hh \ setting.hh \ uniprop.cc uniprop.hh \ util.cc util.hh EXTRA_otftotfm_SOURCES = kpseinterface.c kpseinterface.h otftotfm_LDADD = ../libefont/libefont.a ../liblcdf/liblcdf.a otftotfm_DEPENDENCIES = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_CPPFLAGS = -I$(srcdir)/../include CLEANFILES = @TEMPLATE_OBJS@ EXTRA_DIST = otftotfm.1 if have_kpathsea otftotfm_SOURCES += kpseinterface.c kpseinterface.h AM_CPPFLAGS += $(KPATHSEA_INCLUDES) otftotfm_LDADD += $(KPATHSEA_LIBS) otftotfm_DEPENDENCIES += $(KPATHSEA_DEPEND) endif have_kpathsea ## Rebuild libkpathsea in a TeX Live build @KPATHSEA_RULE@ lcdf-typetools-2.108/otftotfm/otftotfm.10000644000175000017500000014374113423376706015230 00000000000000'\"t .ds V 2.108 .de M .BR "\\$1" "(\\$2)\\$3" .. .de Sp .if n .sp .if t .sp 0.4 .. .de Bp .IP \(bu 3n .. .TH OTFTOTFM 1 "LCDF Typetools" "Version \*V" .SH NAME otftotfm \- create TeX font metrics from OpenType fonts .SH SYNOPSIS .B otftotfm \%[\fB\-a\fR] \%[\fBoptions\fR] \%\fIfontfile\fR [\fItexname\fR] ' .SH DESCRIPTION .BR Otftotfm creates the font metric and encoding files required to use an OpenType font with TeX. You supply an OpenType ".otf" or ".ttf" font file, a base ".enc" encoding, and a TeX name "\fItexname\fR" for the resulting font, and say which OpenType features should be turned on. Then .B otftotfm generates and installs the corresponding TeX-related metric files (".tfm" TeX font metrics, ".vf" virtual fonts, and ".enc" encoding files). It works on both PostScript-flavored and TrueType-flavored OpenType fonts, although TrueType-flavor support will only work easily with pdftex. .LP The easiest way to use .B otftotfm is with the .B \-a option; see Automatic Mode below. Without .BR \-a , .B otftotfm writes all its output files to the current directory. .LP After running "\fBotftotfm\fR \fIfontfile\fR \fItexname\fR" and installing the results (manually or with .BR \-a ), you can use the OpenType font in plain TeX with a command like this: .Sp .nf \efont\emyfont=\fItexname\fR at 10pt {\emyfont This text uses the OpenType font.} .fi .Sp LaTeX users will generally make a ".fd" input file so that commands like "\erenewcommand{\ermdefault}{TeXName}" work correctly. See the EXAMPLE section for more; check the DIAGNOSTICS and FREQUENTLY ASKED QUESTIONS sections if you have trouble. ' .SS "OpenType Features" .LP OpenType fonts support optional .I features that change their appearance. Use the .B \-f option to turn on selected features. For example, "\fB\-f\fRsmcp" replaces lower-case letters with the corresponding small capitals, in fonts that support this. ' .PP You'll generally provide at least the "\fB\-f\fRkern" and "\fB\-f\fRliga" options, which activate pair kerns and f-ligatures. Other interesting features include "\fB\-f\fRcpsp", for capital spacing; "\fB\-f\fRdlig", for optional ligatures; "\fB\-f\fRlnum", "\fB\-f\fRonum", "\fB\-f\fRpnum", and "\fB\-f\fRtnum", to control digit glyphs; "\fB\-f\fRsmcp", for small capitals; "\fB\-f\fRswsh", for swash variants; and "\fB\-f\fRcswh", for contextual swash. See the FEATURE DIRECTORY section below for more. The .M otfinfo 1 program will report which features a font supports; run "\fBotfinfo\fR \fB\-f\fR \fIfontfile\fR". ' .PP Feature options can also apply a feature to a subset of characters in the font. For example, "\fB\-\-lf\fR smcp" .I only replaces letters with small capitals, whereas "\fB\-f\fRsmcp" might additionally replace digits and punctuation marks with small-capital versions. ' .SS Automatic Mode .PP Automatic mode, triggered by the .BR \-a / \-\-automatic option, installs font metrics and encoding files where TeX can find them, and additionally installs a Type 1 font and mapping for .M dvips 1 . This requires a TeX installation that follows the TeX Directory Structure standard (http://www.tug.org/tds/), such as most Unix TeX installations. ' .PP Automatic mode should run seamlessly out of the box. .B Otftotfm will install metrics files, encodings, map files, and Type\~1 fonts into .I $HOME/.texmf-var or any other writable TEXMF directory, and run .M updmap 1 to update the global lists of installed fonts. (On older teTeX installations, you may first need to copy the system's .I updmap.cfg file to .I $HOME/texmf/web2c and run .M mktexlsr 1 . On newer TeXLive installations, you may need to set the TEXMFVAR environment variable.) You can then run "\fBotftotfm\fR .B \-a .IR fontfile .IR texname \&" and immediately refer to the font in TeX using the .I texname you supplied. Again, you will have to write ".fd" files and/or typescripts to make the font conveniently accessible from LaTeX or ConTeXt. See the DIAGNOSTICS section if you have problems with these instructions. ' .PP In automatic mode, .B otftotfm searches your $TEXMFVAR or $TEXMF path for a writable directory, then installs files under that directory tree as follows: ' .TS l l l . \fBFile type\fR \fBDirectory\fR \fBFilename\fR TFM TEXMF/fonts/tfm/\fIvendor\fR/\fItypeface\fR/ \fItexname\fR[\-\-base].tfm VF TEXMF/fonts/vf/\fIvendor\fR/\fItypeface\fR/ \fItexname\fR.vf PL TEXMF/fonts/pl/\fIvendor\fR/\fItypeface\fR/ \fItexname\fR[\-\-base].pl VPL TEXMF/fonts/vpl/\fIvendor\fR/\fItypeface\fR/ \fItexname\fR.vpl encoding TEXMF/fonts/enc/dvips/\fIvendor\fR/ a_\fIsignature\fR.enc or TEXMF/dvips/\fIvendor\fR/ font map TEXMF/fonts/map/dvips/\fIvendor\fR/ \fIvendor\fR.map or TEXMF/dvips/\fIvendor\fR/ .TE .PP "TEXMF" stands for the writable TEXMF directory. \fITexname\fR is the font name supplied as .BR otftotfm 's second argument. The \fIvendor\fR and \fItypeface\fR strings are required by TDS; they default to "lcdftools" and the font's family name, respectively, but see the .B \-\-vendor and .B \-\-typeface options. \fISignature\fR is an opaque 6-character encoding signature. .PP .B Otftotfm also installs a font file suitable for printing. PostScript-flavored OpenType fonts are translated to Type 1 format and installed as PFB fonts. TrueType-flavored fonts are normally installed as is, since pdftex and pdflatex can read TrueType directly; but if you provide the .B \-\-type42 option, .B otftotfm will translate TrueType fonts to Type 42 format, which dvips understands. .B Otftotfm does not overwrite existing font files. .PP The installation paths are as follows, where \fIPSname\fR is the font's PostScript name. .TS l l l . PFB TEXMF/fonts/type1/\fIvendor\fR/\fItypeface\fR/ \fIPSname\fR.pfb TrueType TEXMF/fonts/truetype/\fIvendor\fR/\fItypeface\fR/ \fIfontfile\fR Type 42 TEXMF/fonts/type42/\fIvendor\fR/\fItypeface\fR/ \fIPSname\fR.t42 .TE .PP You can override these directories with environment variables and options as follows. Options take precedence over environment variables. ' .TS l l l . \fBFile type\fR \fBEnvironment variable\fR \fBOption\fR TFM TFMDESTDIR \-\-tfm\-directory VF VFDESTDIR \-\-vf\-directory PL PLDESTDIR \-\-pl\-directory VPL VPLDESTDIR \-\-vpl\-directory encoding ENCODINGDESTDIR \-\-encoding\-directory PFB T1DESTDIR \-\-type1\-directory TrueType TRUETYPEDESTDIR \-\-truetype\-directory Type 42 T42DESTDIR \-\-type42\-directory font map \- \-\-map\-file .TE .PP .B Otftotfm will update the .I TEXMF/ls-R file when installing files under TEXMF. It will also run the .M updmap 1 program after changing a map file, unless the .B \-\-no\-updmap option was supplied. However, if an executable file called .IR TEXMF/dvips/updmap exists, this file is executed (from the .I TEXMF/dvips directory) rather than the global .BR updmap . This is so you can write a fast, customized version of .B updmap if desired. ' .SH EXAMPLE This section uses MinionPro to show one way to install OpenType fonts for LaTeX. We begin with six fonts: "MinionPro-Regular.otf", "MinionPro-It.otf", "MinionPro-Semibold.otf", "MinionPro-SemiboldIt.otf", "MinionPro-Bold.otf", and "MinionPro-BoldIt.otf". .PP Our first task is to decide how to encode the fonts. The "encoding scheme" is used by TeX to decide how to typeset accents and symbols like "$". The "LY1" encoding scheme has reasonable accent support and is a good choice for many OpenType fonts. LY1 corresponds to the "texnansx.enc" encoding file, so we will supply .B otftotfm with the "\fB\-e\fR texnansx" option. .RS .LP Expert note: Strictly speaking, LY1 corresponds to the "texnansi.enc" encoding file. Since the "texnansx.enc" version omits duplicate characters, it has more room for font-specific glyphs and is generally a better choice; but if you plan to type characters like "ae" directly into your editor, rather than using TeX commands like \eae, you should use "texnansi.enc". .RE .PP Next, we decide on a naming scheme for the font metric files. Let's use the OpenType font names as a base. (There's generally no need to follow the six-character "Karl Berry" naming scheme.) Just in case we come back later and add a different encoding scheme, we'll prepend "LY1--" to each name. .PP We're now ready to run .B otftotfm for the first set of fonts. Note the "\fB\-f\fRkern \fB\-f\fRliga" options, which access pair kerns and the default "f" ligatures. .Sp .nf \fBotftotfm\fR \fB\-a\fR \fB\-e\fR texnansx MinionPro\-Regular.otf \e \fB\-f\fRkern \fB\-f\fRliga LY1\-\-MinionPro\-Regular \fBotftotfm\fR \fB\-a\fR \fB\-e\fR texnansx MinionPro\-It.otf \e \fB\-f\fRkern \fB\-f\fRliga LY1\-\-MinionPro\-It \fBotftotfm\fR \fB\-a\fR \fB\-e\fR texnansx MinionPro\-Semibold.otf \e \fB\-f\fRkern \fB\-f\fRliga LY1\-\-MinionPro\-Semibold \fBotftotfm\fR \fB\-a\fR \fB\-e\fR texnansx MinionPro\-SemiboldIt.otf \e \fB\-f\fRkern \fB\-f\fRliga LY1\-\-MinionPro\-SemiboldIt \fBotftotfm\fR \fB\-a\fR \fB\-e\fR texnansx MinionPro\-Bold.otf \e \fB\-f\fRkern \fB\-f\fRliga LY1\-\-MinionPro\-Bold \fBotftotfm\fR \fB\-a\fR \fB\-e\fR texnansx MinionPro\-BoldIt.otf \e \fB\-f\fRkern \fB\-f\fRliga LY1\-\-MinionPro\-BoldIt .fi .Sp The small-caps fonts are generated with an additional "\fB\-f\fRsmcp" option. We append "\-\-fsmcp" to the font metric names as well, differentiating them from the regular fonts. Although MinionPro's italic fonts support small-caps, the LaTeX font selection scheme can't access them easily, so we've left them off. .Sp .nf \fBotftotfm\fR \fB\-a\fR \fB\-e\fR texnansx MinionPro\-Regular.otf \e \fB\-f\fRkern \fB\-f\fRliga \fB\-f\fRsmcp LY1\-\-MinionPro-Regular\-\-fsmcp \fBotftotfm\fR \fB\-a\fR \fB\-e\fR texnansx MinionPro\-Semibold.otf \e \fB\-f\fRkern \fB\-f\fRliga \fB\-f\fRsmcp LY1\-\-MinionPro\-Semibold\-\-fsmcp \fBotftotfm\fR \fB\-a\fR \fB\-e\fR texnansx MinionPro\-Bold.otf \e \fB\-f\fRkern \fB\-f\fRliga \fB\-f\fRsmcp LY1\-\-MinionPro\-Bold\-\-fsmcp .fi .Sp To get old-style numerals, just add the "\fB\-f\fRonum" option to each invocation -- and, to reduce confusion, append "\-\-fonum" to the font metric names. .PP At this point, all our font metric files are installed, and it's finally time to create the ".fd" file. (The ".fd" format is documented in .IR "The LaTeX Companion" .) Let's call the LaTeX font family "MinionPro". Then the ".fd" file is "LY1MinionPro.fd", and it contains: .Sp .nf \eDeclareFontFamily{LY1}{MinionPro}{} \eDeclareFontShape{LY1}{MinionPro}{m}{n}% { <\-> LY1\-\-MinionPro\-Regular }{} \eDeclareFontShape{LY1}{MinionPro}{m}{it}{ <\-> LY1\-\-MinionPro\-It }{} \eDeclareFontShape{LY1}{MinionPro}{m}{sc}% { <\-> LY1\-\-MinionPro\-Regular\-\-fsmcp }{} \eDeclareFontShape{LY1}{MinionPro}{sb}{n}% { <\-> LY1\-\-MinionPro\-Semibold }{} \eDeclareFontShape{LY1}{MinionPro}{sb}{it}% { <\-> LY1\-\-MinionPro\-SemiboldIt }{} \eDeclareFontShape{LY1}{MinionPro}{sb}{sc}% { <\-> LY1\-\-MinionPro\-Semibold\-\-fsmcp }{} \eDeclareFontShape{LY1}{MinionPro}{b}{n}{ <\-> LY1\-\-MinionPro-Bold }{} \eDeclareFontShape{LY1}{MinionPro}{b}{it}% { <\-> LY1\-\-MinionPro\-BoldIt }{} \eDeclareFontShape{LY1}{MinionPro}{b}{sc}% { <\-> LY1\-\-MinionPro\-Bold\-\-fsmcp }{} \eDeclareFontShape{LY1}{MinionPro}{bx}{n}% { <\-> ssub * MinionPro/b/n }{} \eDeclareFontShape{LY1}{MinionPro}{bx}{it}% { <\-> ssub * MinionPro/b/it }{} \eDeclareFontShape{LY1}{MinionPro}{bx}{sc}% { <\-> ssub * MinionPro/b/sc }{} .fi .PP We're now ready to use MinionPro in LaTeX, with lines like this in the document preamble: .Sp .nf \eusepackage[LY1]{fontenc} \erenewcommand{\ermdefault}{MinionPro} \erenewcommand{\ebfdefault}{b} .fi .PP Of course, we're free at any time to add more MinionPro variants with .BR otftotfm ; they'll become accessible to LaTeX as soon as we edit the "MinionPro.fd" file. ' .SH OPTIONS With long options, you need type only as many characters as will make the option unique. .SS Font Feature and Transformation Options .PD 0 .TP 5 .BI \-s " script\fR[.\fIlang\fR], " \-\-script= "script\fR[.\fIlang\fR]" Apply features suitable to the script system .I script and language system .IR lang . Scripts and language systems are two-to-four-letter names assigned by Microsoft and Adobe. Examples include "latn" (Latin script), "grek" (Greek script), and "yi.YIC" (Yi script with classic characters). If .I lang is not specified, .B otftotfm will use the default language system for that script. You can give this option multiple times. Run "\fBotfinfo\fR \-s \fIfont\fR" to see the list of scripts and languages a font supports. Defaults to "latn". ' .Sp .TP 5 .BI \-f " feature\fR, " \-\-feature= "feature" Activate the feature named .IR feature . Features are four-letter names assigned by Microsoft and Adobe; they are meant to correspond to font behaviors, such as kerning or small-capitals. Examples include "liga" (default ligatures), "dlig" (discretionary ligatures), "kern" (kerning), and "c2sc" (replacing capitals with small capitals). Give this option multiple times to apply multiple features. Run "\fBotfinfo\fR \-f [\-\-script option] \fIfont\fR" to see the list of features a font supports for a specified script. Defaults to any features required by the selected scripts. ' .Sp .TP 5 .BI \-\-lf " feature\fR, " \-\-letter\-feature= "feature" Activate the feature named .IR feature , but only for letters. For instance, the "\-f smcp" option will apply the small-caps feature to all characters in the encoding; this may result in changes to punctuation and numbers as well as letters. The "\-\-lf smcp" option will apply the small-caps feature only to letters, meaning characters with the "Letter" Unicode property. ' .Sp .TP 5 .BI \-\-subs\-filter " pattern" .TP 5 .BI \-\-include\-subs " pattern" .TP 5 .BI \-\-exclude\-subs " pattern" .TP 5 .BI \-\-clear\-subs Limit the characters that .B otftotfm will substitute. Substitution is allowed on an input character if it matches at least one of the .B \-\-include patterns, and none of the .B \-\-exclude patterns. Each pattern applies to all following features, except that the .B \-\-clear option clears any accumulated patterns. The .BI \-\-subs\-filter " pattern" option acts like .B \-\-clear\-subs followed by .BI \-\-include\-subs " pattern\fR. " For pattern syntax, see GLYPH PATTERNS, below. .Sp In the command line below, the \&'' pattern will force the "onum" feature to substitute only numbers (and not, for example, punctuation). The "salt" feature can still substitute any character. .nf \fBotftotfm\fR \fB\-f\fRsalt \fB\-\-include\-subs\fR="" \fB\-f\fRonum \.\.\. .fi ' .Sp .TP 5 .BI \-E " fac\fR, " \-\-extend= fac Widen, or extend, the font by a factor of .IR fac . Like .M afm2tfm 1 's .B \-e option. ' .Sp .TP 5 .BI \-S " amt\fR, " \-\-slant= amt Oblique, or slant, the font by .IR amt . Like .M afm2tfm 1 's .B \-s option. ' .Sp .TP 5 .BI \-L " amt\fR, " \-\-letterspacing= amt Letterspace each character by .IR amt units, where 1000 units equals one em. The width of each character increases by .IR amt , with half the space distributed to each sidebearing. Boundary-character kerns are added to maintain alignment at the ends of lines. ' .Sp .TP 5 .BR \-\-math\-spacing "[=\fIskewchar\fR]" Ignore the font's claimed character widths, deriving horizontal metrics from bounding boxes instead. This results in similar spacing as the Computer Modern Math Italic font, with increased sidebearings for letters like f and j. .Sp If you provide .IR skewchar , a number between 0 and 255 or a single character, then .B otftotfm adds heuristically-derived kerns to the font that may improve accent positions in math mode. To get the benefits, you must tell TeX about the .I skewchar with a command like "\eskewchar\efont=\fIskewchar\fR". ' .Sp .TP 5 .BI "\-k " "N\fR, " \-\-min\-kern= N Only output kerning pairs whose absolute value is .IR N or larger. Larger minimum kerns make kerning less precise, but shrink the output TFM file. The default minimum kern is 2.0, or 0.002 em. ' .Sp .TP 5 .BI \-\-space\-factor= fac Scale the width of the inter-word space by a factor of .IR fac . ' .Sp .TP 5 .BI \-\-design\-size= size Set the output font's design size to .IR size , a value in TeX points. This value is mostly just documentation, since LaTeX essentially ignores fonts' design sizes, but plain TeX may occasionally use the design size to decide how large a font should be. (Loading a font in TeX "at" a particular size effectively ignores the design size; loading a font plain or "scaled" by a given factor uses the design size.) The default is taken from the input font's optical size feature, or 10pt if it has no such feature. ' .Sp .TP 5 .BI \-\-fixed\-width Set the font to fixed-width (its space character will have no stretch or shrink). Normally you won't need this option; the font will tell .B otftotfm whether it is fixed width. The opposite of .B \-\-fixed\-width is .BR \-\-proportional\-width . ' .Sp .TP 5 .BI \-\-italic\-angle= angle Set the output font's default italic angle to .IR angle , a number of degrees. This value is used by TeX to position accents. Normally you won't need this option; the font will tell .B otftotfm its italic angle. .PD ' .Sp .TP 5 .BI \-\-x\-height= val Set the output font's x-height to .IR val . This value is used by TeX to position accents. Normally you won't need this option. .IR Val may be a number expressed in font units; \(oqx\(cq, which uses the height of the font's lowercase x; or \(oqfont\(cq, which uses the font's declared x-height metric. ' .SS Encoding Options ' .PD 0 .TP 5 .BI \-e " encoding\fR, " \-\-encoding= encoding Select the output metrics's base .M dvips 1 encoding. .B Otftotfm will search for .IR encoding [.enc] the same way that .B dvips would, so you may not need to give a full pathname. Say .B \-e \- to start with the font's default encoding. See ENCODINGS, below, for more information. ' .Sp .TP 5 .BI \-\-boundary\-char= char Set the font's boundary character to .IR char , which should either be a single non-digit character, or a number between \-1 and 255. The default is taken from the encoding. ' .Sp .TP 5 .BI \-\-altselector\-char= char Set the font's alternate selector character to .IR char , which should either be a single non-digit character, or a number between \&\-1 and 255. Alternate selectors let TeX authors explicitly choose between versions of a character. For instance, the \&'\-\-altselector\-char="*"' option turns the "*" character into a special switch that cycles between alternates. For instance, the TeX input "A" would produce the normal version of the "A" Unicode character, "A*" would produce the first alternate, "A**" would produce the second alternate, and so forth. Furthermore, "s*t" will activate any discretionary "s_t" ligature in the font. .Sp The .B \-\-altselector\-char mechanism uses the features specified by .BR \-\-altselector\-feature options. .Sp The alternate-selector character may also be specified in the encoding; see ENCODINGS, below. See Sivan Toledo's article cited in the SEE ALSO section for more information. ' .Sp .TP 5 .BI \-\-altselector\-feature= feature Activate the feature named .I feature for the .B \-\-altselector\-char mechanism. Give this option multiple times to activate multiple features. This option activates features only for use with .BR \-\-altselector\-char ; use the .B \-\-feature option to activate features globally. Defaults to the .I salt and .I dlig features. ' .Sp .TP 5 .BI \-\-alternates\-filter= pattern .TP 5 .BI \-\-include\-alternates= pattern .TP 5 .BI \-\-exclude\-alternates= pattern .TP 5 .BI \-\-clear\-alternates Limit the alternate characters that .B otftotfm will select. An alternate is used if it matches at least one of the .B \-\-include patterns, and none of the .B \-\-exclude patterns. Each pattern applies to all following features, except that the .B \-\-clear option clears any accumulated patterns. The .BI \-\-alternates\-filter " pattern" option acts like .B \-\-clear\-alternates followed by .BI \-\-include\-alternates " pattern\fR. " For pattern syntax, see GLYPH PATTERNS, below. .Sp OpenType fonts can have many alternates per character, most of which aren't interesting. For example, the character "a" in WarnockPro-Regular has five alternates, "ordfeminine", "Asmall", "asuperior", "a.end", and "orn.013". The .B \-\-altselector\-char option lets you cycle through these alternates, but it's better to leave out the ones you don't want, to avoid overfull encodings. Thus, if you were only interested in ".end" variants, you might supply an \&'\-\-include\-alternates="*.end"' option. .Sp In the command line below, the \&'*.end' pattern will apply to "aalt" alternates, but not to "salt" alternates. .nf \fBotftotfm\fR \fB\-f\fRsalt \fB\-\-include\-alternates\fR="*.end" \fB\-f\fRaalt \.\.\. .fi ' .Sp .TP 5 .BI \-\-ligkern= command Add a LIGKERN .IR command to the encoding. For example, \&'\fB\-\-ligkern\fR "T {L} h"' suppresses any T_h ligature in the font. You can supply multiple .B \-\-ligkern options. See ENCODINGS, below. ' .Sp .TP 5 .BI \-\-position= command Add a POSITION .IR command to the encoding. For example, \&'\fB\-\-position\fR "T 10 0 20"' adds ten units of space to either side of the "T" character. You can supply multiple .B \-\-position options. See ENCODINGS, below. ' .Sp .TP 5 .BI \-\-unicoding= command Add a UNICODING .IR command to the encoding. For example, \&'\fB\-\-unicoding\fR "pi1 =: uni03D6"' tells .B otftotfm to encode "/pi1" as U+03D6 GREEK PI SYMBOL. You can supply multiple .B \-\-unicoding options. See ENCODINGS, below. ' .Sp .TP 5 .BI \-\-no\-encoding\-commands Ignore any LIGKERN and/or UNICODING commands in the encoding file. ' .Sp .TP 5 .BI \-\-no\-default\-ligkern Don't include .BR otftotfm 's default LIGKERN commands. ' .Sp .TP 5 .BI \-\-coding\-scheme= scheme Add a CODINGSCHEME to the encoding. See ENCODINGS, below. ' .Sp .TP 5 .BI \-\-warn\-missing Warn about encoded characters not supported by the font. See the WARNMISSING command in ENCODINGS, below. ' .Sp .TP 5 .BI \-\-literal\-encoding= encoding Select the .M dvips 1 encoding used for the font. No glyph substitutions will be permitted, so the output encoding will equal the input encoding (and .B otftotfm will not generate an output encoding). ' .Sp .TP 5 .BI \-\-base\-encodings= file .B Experts only. Allow the output font to refer to existing "base" fonts. This can greatly reduce the number of base fonts generated by .BR otftotfm ". " Each line in the .I file argument contains a TeX font name (as for .BR \-\-name ) and a corresponding literal encoding file (as for .BR \-\-literal\-encoding ); for example: .nf WarnoProReg\-\-eka eka WarnoProReg\-\-exp1 exp1 .fi The named fonts must have been created by prior runs of .B otftotfm on the same input OpenType font, with the same .BR \-\-extend and .BR \-\-slant options as the current run. The current output font will refer to glyphs from the named base fonts when possible. If the base fonts cover all glyphs required by the output font, .B otftotfm won't generate any new base fonts at all. The .I file can also refer to dotless-J fonts using the following syntax: .nf WarnoProReg\-\-lcdfj \- dotlessj .fi ' .PD ' ' .SS Automatic Mode Options ' .PD 0 .TP 5 .BI \-a "\fR, " \-\-automatic Select automatic mode. ' .Sp .TP 5 .BI \-v " vendor\fR, " \-\-vendor= vendor Set the font vendor name, which is used to locate files within the TDS. Defaults to "lcdftools". .Sp In automatic mode, TeX and friends will generally find required font files independently of the vendor you select. ' .Sp .TP 5 .BI \-\-typeface= typeface Set the font typeface name, which is used to locate files within the TDS. Defaults to the current font's family name with unsuiable characters removed. ' .Sp .TP 5 .BI \-\-no\-type1 Do not use .M cfftot1 1 to create Type 1 fonts corresponding to the OpenType input fonts. ' .Sp .TP 5 .BI \-\-no\-dotlessj Do not use .M t1dotlessj 1 to create a special dotless-j font when the input font doesn't have dotless-j. ' .Sp .TP 5 .BI \-\-no\-truetype Do not install TrueType-flavored fonts. ' .Sp .TP 5 .BI \-\-type42 Install TrueType-flavored fonts in translated Type 42 format. ' .Sp .TP 5 .BI \-\-no\-updmap Do not run an .M updmap 1 program. This can be useful if you're installing a bunch of fonts; it is much faster to run .B updmap once, at the end, than to run it once per font. .PD ' ' .SS Output Options .PD 0 .TP 5 .BI \-n " texname\fR, " \-\-name= texname Set the TeX name of the output font, which is used in font map files and, in automatic mode, to generate the output filename. The default is derived from the OpenType font's name and the features you selected. ' .Sp .TP 5 .BI \-p "\fR, " \-\-pl Output human-readable PL and VPL metrics, not binary TFM and VF metrics. Note: .BR Otftotfm 's PL and VPL output files are legal, but the .B fontinst program may not accept them (it has a picky parser). Make sure to supply a .BR \-\-coding\-scheme ; if that doesn't help, run the TFM output through .M tftopl 1 . ' .Sp .TP 5 .BI \-\-no\-virtual Do not generate virtual fonts (VFs and VPLs). .B Otftotfm will warn if the selected font features cannot be implemented without virtual fonts. ' .Sp .TP 5 .BI \-\-no\-encoding Do not generate an encoding file. ' .Sp .TP 5 .BR \-\-output\-encoding [=\fIfile\fR] Only generate an encoding file; do not generate any other output. The encoding file is written to .IR file , or to standard output if no .I file argument is supplied. ' .Sp .TP 5 .BI \-\-no\-map Do not generate a font map line for the font. ' .\" .Sp .\" .TP 5 .\" .BI \-\-base\-name name .\" Experts only: Set the TeX name of the "base" output font. When .\" .B otftotfm .\" needs to make a virtual font (because of font features and/or .\" letterspacing), it must generate at least two TFM metrics files, one for .\" the base font and one for the virtual font. In some cases, multiple .\" virtual fonts can share the same base metrics, reducing the number of .\" installed metrics files. This option lets you explicitly set the name of .\" the base output font independently from the main output font, and thus .\" force fonts to share base metrics. The default base name is derived from .\" the TeX name, with "\f(CW\-\-base\fR" appended. .PD ' ' .SS File Location Options .PD 0 .TP 5 .BI \-\-tfm\-directory= dir .TP 5 .BI \-\-pl\-directory= dir .TP 5 .BI \-\-vf\-directory= dir .TP 5 .BI \-\-vpl\-directory= dir .TP 5 .BI \-\-encoding\-directory= dir .TP 5 .BI \-\-type1\-directory= dir .TP 5 .BI \-\-truetype\-directory= dir .TP 5 .BI \-\-type42\-directory= dir .TP 5 .BI \-\-directory= dir Set the directory used for various output types. Each directory may be set by an environment variable, and defaults to a TDS directory in automatic mode, or to "." otherwise. Environment variable names and default TDS locations are described in the Automatic Mode section above. The .B \-\-directory option sets the default directory for all output types. ' .Sp .TP 5 .BI \-\-map\-file= filename Set file in which .B otftotfm will write a font map line for the font. The default is the standard output in manual mode, and "TEXMF/fonts/map/dvips/\fIvendor\fR/\fIvendor\fR.map" (or "TEXMF/dvips/\fIvendor\fR/\fIvendor\fR.map" on older installations) in automatic mode. .PD ' ' .SS Miscellaneous Options .PD 0 .TP 5 .BI \-\-glyphlist= file Use .I file as a Adobe glyph list, which helps translate glyph names to Unicode code points. Give multiple options to include multiple files. See ENCODINGS, below, for more information. ' .Sp .TP 5 .BR \-V ", " \-\-verbose Write progress messages to standard error. ' .Sp .TP 5 .BR \-\-no\-create Do not create or modify any files. Instead, write messages about the program's hypothetical progress to standard error. ' .Sp .TP 5 .BR \-\-force Generate all files, even if it looks like versions are already installed. ' .Sp .TP 5 .BR \-q ", " \-\-quiet Do not generate any error messages. ' .Sp .TP 5 .BI \-\-kpathsea\-debug= flags Set path searching debugging flags. See the .I Kpathsea manual for details. ' .Sp .TP 5 .BR \-h ", " \-\-help Print usage information and exit. ' .Sp .TP 5 .BR \-\-version Print the version number and some short non-warranty information and exit. .PD ' .SH ENCODINGS .B Otftotfm interprets encoding files as Unicode. For example, say an input encoding has "/dotlessi" at position 10. .B Otftotfm detects that position 10 should contain Unicode character U+0131 LATIN SMALL LETTER DOTLESS I, and uses the font's glyph for that character (possibly modified by any active features). The selected glyph might not be named "dotlessi"; only the Unicode value matters. .PP .B Otftotfm assigns Unicode values to glyph names using a table published by Adobe (SEE ALSO has a reference), with extensions for TeX. For more fine-grained control, add UNICODING commands to the input encoding file. These commands have the following format: .nf % UNICODING \fIglyph\fR =: \fIchoice1\fR [\fIchoice2\fR ...] ; .fi This tells .B otftotfm that the glyph named .I glyph translates into the first Unicode value in the .I choice list that has a character in the font. \fIGlyph\fR and the .IR choice s are PostScript glyph names; the initial "%" sign is required; and each UNICODING line can contain multiple commands, separated by spaced semicolons. For example, .nf % UNICODING pi1 =: uni03D6 ; .fi encodes the character "/pi1" as U+03D6 GREEK PI SYMBOL, and .nf % UNICODING Delta =: uni0394 uni2206 ; .fi makes U+0394 GREEK CAPITAL LETTER DELTA preferred to U+2206 INCREMENT as an encoding for "/Delta". You can also supply glyph names: .nf % UNICODING Delta =: Deltagreek Delta ; .fi A mapping with no Unicode values removes that glyph from the input encoding. For instance, this erases any f-ligature characters from the encoding: .nf % UNICODING ff =: ; fi =: ; fl =: ; ffi =: ; ffl =: ; .fi The slots are available for .BR otftfm 's own use, for example for other characters required by the font. (If the f-ligatures themselves are required by the font, for instance by a \&'liga' feature, then they will be stored into their old slots when possible.) Map a glyph to \&'emptyslot' if you don't want .B otftotfm to use the slot. For example, this will leave the \&'ff' slot unused if the font has no \&'ff' glyph: .nf % UNICODING ff =: ff emptyslot ; .fi (Note that most OpenType fonts provide a visible representation for unused encoding slots, namely a box with an X inside.) .PP LIGKERN comments in the encoding can add ligatures and inhibit kerns, as in .M afm2tfm 1 . To add a ligature, say: .nf % LIGKERN \fIglyph1\fR \fIglyph2\fR =: \fIresult\fR ; .fi The "=:" operator indicates a normal ligature, where both the input glyphs are removed and replaced by .IR result . To preserve the left-hand glyph, for an effect like "\fIglyph1\fR \fIglyph2\fR =: \fIglyph1\fR \fIresult\fR", use "|=:" instead; to preserve the right-hand glyph, use "=:|". .\" The other five ligature operators are not yet supported. To remove all kerns between two characters, say: .nf % LIGKERN \fIglyph1\fR {} \fIglyph2\fR ; .fi A "*" matches any character, so .nf % LIGKERN a {} * ; .fi removes all kerns with "a" as the left-hand character, and .nf % LIGKERN * {} * ; .fi removes all kerns. .PP .B Otftotfm also supports extended syntax for setting kern values and inhibiting ligatures. To add an \fIn\fR-unit kern between two glyphs, say: .nf % LIGKERNX \fIglyph1\fR {\fIn\fR} \fIglyph2\fR ; .fi where \fIn\fR is an integer. This: .nf % LIGKERNX \fIglyph1\fR {L} \fIglyph2\fR ; .fi inhibits any ligature between .I glyph1 and .IR glyph2 . "{LK}" and "{KL}" inhibit both ligatures and kerns. .PP You can set the .B \-\-boundary\-char and .B \-\-altselector\-char from an encoding file with commands like this: .nf % LIGKERN || = \fIboundarychar\fR ; % LIGKERNX ^^ = \fIaltselectorchar\fR ; .fi As with UNICODING, each LIGKERN or LIGKERNX line can contain multiple commands, separated by spaced semicolons. .PP .B Otftotfm has a default set of eight ligatures, namely: .nf space l =: lslash ; space L =: Lslash ; question quoteleft =: questiondown ; exclam quoteleft =: exclamdown ; hyphen hyphen =: endash ; endash hyphen =: emdash ; quoteleft quoteleft =: quotedblleft ; quoteright quoteright =: quotedblright .fi LIGKERN commands in the encoding file and .B \-\-ligkern options can override these defaults, or supply the .B \-\-no\-default\-ligkern option to turn them off. .PP The POSITION command shifts a glyph within its bounding box. The syntax is .nf % POSITION \fIglyph\fR \fIpdx\fR \fIpdy\fR \fIadx\fR ; .fi This will add .I pdx units of space to .IR glyph 's left edge; raise it up by .I pdy units; and add .I adx units to its width. For example, to add 10 units of space to either side of the "T" glyph, supply .nf % POSITION T 10 0 20 .fi To move the "degree" symbol up by 20 units, supply .nf % POSITION degree 0 20 0 .fi .PP The CODINGSCHEME command specifies the coding scheme for fonts using this encoding. This is a string, less than 40 characters long and containing no parentheses, that classifies the encoding for TeX's purposes. Sample coding schemes include "TEX TEXT", "TEX MATH ITALIC", and "EXTENDED TEX FONT ENCODING - LATIN". For example: .nf % CODINGSCHEME EXTENDED TEX FONT ENCODING - LATIN .fi Most tools ignore the coding scheme; fontinst is an exception. .B Otftotfm uses the encoding's PostScript name for the default coding scheme. .PP Finally, the WARNMISSING command makes any glyphs not supported by the input font appear as black boxes. The .M dvips 1 processor will also print a warning when encountering these glyphs. For example: .nf % WARNMISSING yes .fi .PP The .BR \-\-unicoding , .BR \-\-ligkern , .BR \-\-position , .BR \-\-coding\-scheme , and .B \-\-warn\-missing options add UNICODING, LIGKERN/LIGKERNX, POSITION, CODINGSCHEME, and WARNMISSING commands to an encoding, and can override commands in the encoding itself. Some common encoding files have commands that are inappropriate for OpenType fonts; for example, "t1.enc" hard-codes f-ligatures, which can cause problems with small-cap fonts. Supply the .B \-\-no\-encoding\-commands option to ignore all commands from the encoding file. Commands from options like .B \-\-ligkern are processed in any case. ' .SS New Glyphs .PP New glyphs, such as ligatures and contextual substitutions, are added to the encoding in any empty spaces, using their original locations when possible. If the encoding doesn't have enough space for all new glyphs, shorter ligatures composed of unaccented letters get precedence. ' .SS Synthetic Glyphs .PP .B Otftotfm can synthesize some glyphs using virtual font manipulations, if a required glyph is not available in the input font. Specifically, it will synthesize: .Sp .PD 0 .TP 22 cwm TeX's compound word mark (a zero-width "strut" rule with height equal to the font's x-height) .TP ascendercompwordmark "cwm" with height equal to the font's ascenders .TP capitalcompwordmark "cwm" with height equal to the font's capitals .TP visualspace A square cup used to represent spaces .TP dotlessj A dotless "j", synthesized with .M t1dotlessj 1 .TP dblbracketleft Kerned version of "[[" .TP dblbracketright Kerned version of "]]" .TP bardbl The parallel symbol "||" .TP asteriskmath Vertically-centered "*" .TP ringfitted Ring accent centered on the width of "A" .TP twelveudash 2/3-em-wide dash .TP threequartersemdash 3/4-em-wide dash .TP centigrade "(degrees)C" .TP interrobang Combined "?!" symbol .TP interrobangdown Inverted interrobang .TP pertenthousand Per-ten-thousand sign (% with two extra 0s) .TP IJ "IJ" ligature .TP ij "ij" ligature .TP Germandbls "SS" (a capital sharp-s) .TP SSsmall Small-capital version of "SS" .TP FFsmall Small-capital version of "FF" .TP FIsmall Small-capital version of "FI" .TP FLsmall Small-capital version of "FL" .TP FFIsmall Small-capital version of "FFI" .TP FFLsmall Small-capital version of "FFL" .PD ' ' .SH "GLYPH PATTERNS" .LP The .BR \-\-include\-subs and .BR \-\-include\-alternates options, and their .B \-\-exclude and .B \-\-*\-filter variants, accept the following types of pattern. .Bp Glyph names. Example: "Aacute". For PostScript-flavored fonts, use .M otfinfo 1 's .B \-g option to see a font's glyph names, and "\fBcfftot1\fR \fIfont\fR.otf | \fBt1testpage\fR" to generate a PostScript file showing each glyph. .Bp Glyph name patterns using the shell-style glob-matching rules: "*" matches any number of characters, "?" matches any single character, and "[...]" matches any character in a set. Example: "*.end". .Bp Unicode category properties in angle brackets. Examples: "", "", "". The complete list of both short and long names: Letter/L, UppercaseLetter/Lu, LowercaseLetter/Ll, TitlecaseLetter/Lt, ModifierLetter/Lm, OtherLetter/Lo; Number/N, DecimalNumber/Nd, LetterNumber/Nl, OtherNumber/No; Punctuation/P, ConnectorPunctuation/Pc, DashPunctuation/Pd, OpenPunctuation/Ps, ClosePunctuation/Pe, InitialPunctuation/Pi, FinalPunctuation/Pf, OtherPunctuation/Po; Symbol/S, MathSymbol/Sm, CurrencySymbol/Sc, ModifierSymbol/Sk, OtherSymbol/So; Mark/M, SpacingMark/Mc, EnclosingMark/Me, NonspacingMark/Mn; Separator/Z, SpaceSeparator/Zs, LineSeparator/Zl, ParagraphSeparator/Zp; Other/C, Surrogate/Cs, Format/Cf, Control/Cc, PrivateUse/Co, Unassigned/Cn. Category values current as of Unicode 4.0. .Bp Unicode ranges. Example: "U+007f-U+008C". .PP The "!" prefix negates a pattern, and you can separate multiple patterns by spaces. ' .SH "FEATURE DIRECTORY" .LP This section lists features common to Western OpenType fonts and describes how .B otftotfm handles them for common fonts. Please send the author mail if .B otftotfm does not handle a feature you need, or you believe it handles some feature incorrectly. .Sp .PD 0 .TP 5 .IR aalt ", Access All Alternates" Lets the user choose between all available alternate forms for a character. This includes things like superscript and subscript variants, different styles (swash, for example), and even ornaments. The .BR \-\-altselector\-feature= aalt option can help an .BR \-\-altselector\-char provide useful access to alternates, but the .I aalt feature isn't usually useful on its own. Try the .IR salt " and " calt features instead. .TP 5 .IR c2sc ", Small Capitals From Capitals" Replaces capital letters with small capitals: a sort of converse of the more conventional .I smcp feature, which replaces lower-case letters with small capitals. Supported. .TP 5 .IR calt ", Contextual Alternates" Lets the user choose between context-appropriate swash forms for each character. For example, given the word "DREW" in a cursive typeface, the "R E W" might be translated to calmer forms than the initial "D". There may be more than one choice for a given letter, in which case the user should be able to select among them. TeX can't support complex contextual alternates, or alternate selection, but .B otftotfm supports some fonts quite well. The input encoding should have lots of empty space for variants, and it should specify a boundary character. See also .IR cswh . .TP 5 .IR case ", Case-Sensitive Forms" Shifts punctuation marks up to a position that works well with all-capital-letter sequences. For example, the hyphen character, which generally centers vertically on the x-height, is raised up to center vertically on a capital letter. Also replaces text figures with lining figures, and accent marks with forms more appropriate for capitals. Supported. .TP 5 .IR cpsp ", Capital Spacing" Adds a bit of space on either side of each capital letter. Supported. (However, the OpenType tag registry suggests that .I cpsp be on by default, but applying to all-caps text only; TeX cannot easily implement that contextual intelligence.) .TP 5 .IR cswh ", Contextual Swash" Lets the user choose between context-appropriate swash forms for each character. For example, in the words "Ab AC", the first "A" might be translated to a swash form, while the second might not. There may be more than one choice for a given letter, in which case the user should be able to select among them. .B Otftotfm supports some fonts quite well. The input encoding should have lots of empty space for swash variants, and it should specify a boundary character. See also .IR calt " and " swsh . .TP 5 .IR dlig ", Discretionary Ligatures" Activates uncommon ligatures, such as "c_t", "s_p", and "s_t". Supported. .TP 5 .IR dnom ", Denominators" Replaces digits and some punctuation marks with smaller forms sitting on the baseline, intended for fraction denominators. Supported. .TP 5 .IR fina ", Terminal Forms" Substitutes appropriate forms for letters occurring at the ends of words. This feature doesn't select swash variants; it's intended for normal use, and the specification recommends that it be on by default. Partially supported: TeX will only treat spaces as the ends of words, where a correct implementation would probably include punctuation too. See .IR cswh for selecting swash variants active at the ends of words. .TP 5 .IR frac ", Fractions" Replaces simple sequences like "1/2" with nice-looking fractions. Supported, but beware: many fonts will translate "11/32" into "1" + "1/3" + "2". .TP 5 .IR hist ", Historical Forms" Replaces characters with historical variants. Usually, this means at least translating regular "s" to long "s". Supported. .TP 5 .IR kern ", Kerning" Adjusts the space between characters (pair kerning). Generally supported, and you should probably turn it on. As a special case, "\fB\-f\fRkern" can also read kerning information from the "kern" table in conventional TrueType fonts. .TP 5 .IR liga ", Standard Ligatures" Activates common ligatures, such as "f_f", "f_i", "f_f_j", and (in some Adobe fonts) "T_h". Generally supported, and you should probably turn it on. .TP 5 .IR lnum ", Lining Figures" Uses lining figures, the set of digits that are all about as high as capital letters. Supported. Compare .IR onum ; see also .IR pnum and .IR tnum. .TP 5 .IR numr ", Numerators" Replaces digits and some punctuation marks with smaller, raised forms intended for fraction numerators. Supported, but not usually useful. .TP 5 .IR onum ", Oldstyle Figures" Uses old-style figures, also known as text figures. This is the set of digits that have ascenders and descenders like lower-case letters. Supported. Compare .IR lnum ; see also .IR pnum and .IR tnum . .TP 5 .IR ordn ", Ordinals" Designed for Spanish and French. Replaces ordinal numbers, such as "2.o", with forms where the "o" is raised, and replaces the sequence "No" with an integrated glyph. Supported. .TP 5 .IR ornm ", Ornaments" Replaces some alphabetic characters in the font with ornaments, and links the bullet character to a set of all bullet-like ornaments, from which the user can choose. Partially supported: TeX can handle alphabetic substitutions, but not bullet choice. .TP 5 .IR pnum ", Proportional Figures" Digits will have different widths. Supported. Compare .IR tnum ; see also .IR lnum and .IR onum. .TP 5 .IR salt ", Stylistic Alternates" Lets the user choose between stylistic alternate forms for a character. The .BR \-\-altselector\-char mechanism provides useful access to this feature. If you turn on .IR salt globally, .B otftotfm takes the first alternate form whenever there's more than one choice. See also .IR aalt and .IR ss01 ; .IR salt is generally more useful than .IR aalt for TeX, since it refers exclusively to stylistic alternates. .TP 5 .IR sinf ", Scientific Inferiors" Replaces digits and some punctuation marks with smaller, lowered forms intended for subscripts. Supported. Compare .IR subs . .TP 5 .IR size ", Optical Size" This feature stores information about the range of optical sizes for which the font was intended. There is no point in selecting it with .BR otftotfm , since it should not change the font's appearance in any way. .TP 5 .IR smcp ", Small Capitals" Replaces lower-case letters with small capitals. Supported. Compare .IR c2sc . .TP 5 .IR ss01 - ss20 ", Stylistic Sets 1-20" Replaces characters with a uniform set of stylistic alternates. Differs from features like .I salt in that a Stylistic Set is uniform: an .I ssXX feature should never involve selection from a set of possible alternate characters. Supported. .TP 5 .IR subs ", Subscript" Replaces characters with smaller, lowered forms intended for subscripts. Supported. Compare .IR sinf ; some fonts support .I sinf but not .IR subs . .TP 5 .IR sups ", Superscript" Replaces digits, some punctuation marks, and some lower-case letters with smaller, raised forms intended for superscripts. Supported. .TP 5 .IR swsh ", Swash" Activates all swash forms for each character. There may be more than one swash form, in which case .B otftotfm will pick the first one listed. Supported, except that swash variants other than the first are inaccessible. Note that some fonts with swash variants support the .I cswh feature exclusively. .TP 5 .IR tnum ", Tabular Figures" All digits will have the same width, so that tables and the like will align visually. Supported. Compare .IR pnum ; see also .IR lnum and .IR onum. .TP 5 .IR zero ", Slashed Zero" Replaces the zero character with a slashed zero. Supported. .PD ' .SH "DIAGNOSTICS AND TROUBLESHOOTING" ' .TP 5 no writable directory found in $TEXMF ' .B Otftotfm could not find a writable directory in your $TEXMFVAR or $TEXMF path. Did you create a .I $HOME/.texmf-var or .I $HOME/texmf directory? If so, run the command "kpsewhich \-\-expand\-path='$TEXMF'" to verify that directory is not being found. You may need to set your TEXMF environment variable, to \&'{!!'"$HOME"'/texmf,!!$TEXMFMAIN}', for instance (note the different kinds of quotes; on my machine, this expands to \&'{!!/home/kohler/texmf,!!$TEXMFMAIN}'). ' .TP 5 \&'\fIchar\fR' has no encoding, ignoring kern removal .PD 0 .TP 5 (or ligature removal, lig/kern removal, or ligature) .PD ' These messages indicate a slight problem with your encoding file: one of the LIGKERN commands referred to a character not present in the encoding. This might be due to a misspelling in the LIGKERN command or the encoding file, or it might be an oversight. Either fix the encoding file or ignore the warning. ' .TP 5 can't map \&'\fIchar\fR' to Unicode ' Another encoding file problem: One of the glyph names in an UNICODING block could not be converted to Unicode. This is problematic since UNICODING exists wholly to translate glyph names into Unicode. Fix the encoding file or ignore the warning. ' .TP 5 not enough room in encoding, ignoring \fIN\fR glyph(s) ... ' There wasn't space in the encoding for all the glyphs referred to by the features you selected. For example, maybe the font had more ligatures than there were empty slots in the encoding. Fix this warning by selecting fewer features, or by using an encoding with more empty slots, such as the 7t.enc encoding distributed with .BR otftotfm . ' .TP 5 The \&'\fB\-a\fR' option did not install my font correctly. ' Try again with the \&'\fB\-\-verbose\fR' option, which causes .BR otftotfm to explain its behavior. Note that by default, .BR otftotfm will not re-install files already present in your system's TeX search paths (in the current directory, for instance). Use \&'\fB\-\-force\fR' to override this behavior. ' .SH "FREQUENTLY ASKED QUESTIONS" .TP 5 How can I get a small-caps "SS" in place of the German sharp-S? ' Supply the option \&'\fB\-\-unicoding\fR "germandbls =: SSsmall"'. ' .TP 5 How can I prevent f-ligatures from forming in a small-caps font? ' This should happen automatically, but some overzealous encoding files add f-ligatures even when the font doesn't request them. Try the "\fB\-\-no\-encoding\-commands\fR" option if this is a problem for you. ' .TP 5 \fBOtftotfm\fR seems to take a long time. ' Use the .B \-V option to see what it's doing. Often the culprit is the .M updmap 1 program; if you're planning to run .B otftotfm multiple times, give it the .B \-\-no\-updmap option and run .B updmap manually when you're done. ' .TP 5 How can I refer to the different forms of phi? ' \fBOtftotfm\fR follows TeX practice and widely-distributed TeX encoding vectors, so "/phi" in an input encoding vector should map to a "straight" phi and "/phi1" should map to a "loopy" phi. Note that TeX practice differs from the PostScript standard naming conventions, in which "/phi" is "loopy" and "/phi1" is "straight"; this means that \fBotftotfm\fR may map "/phi" in an input encoding vector to a font's "/phi1" glyph, and vice versa. Perhaps most unambiguously, you can use "/uni03D5" for the "straight" form and "/uni03C6" for the "loopy" form. ' .TP 5 How can I get lining figures (that is, normal line-height digits) with small caps ('\fB\-f\fRsmcp')? ' Many fonts use old-style figures by default with small caps. Since the default is not specified, it's wise to explicitly supply \&'\fB\-f\fRlnum' or \&'\fB-f\fRonum'. ' .SH "BUGS" .\" .LP .\" Presumably some context-sensitive positionings and ligatures could be .\" implemented with TeX's boundary character, but .\" .B otftotfm .\" doesn't do that yet. .LP See the documentation for .B \-\-pl above if you have problems running .BR otftotfm 's output through .BR fontinst . ' .SH "SEE ALSO" .LP .M pltotf 1 , .M tftopl 1 , .M vptovf 1 , .M afm2tfm 1 , .M dvips 1 , .M cfftot1 1 , .M otfinfo 1 , .M t1dotlessj 1 , .M t1testpage 1 , .M ttftotype42 1 , .M kpsewhich 1 , .M updmap 1 .LP .I "Adobe Type 1 Font Format" .LP Adobe Technical Notes #5176, .IR "The Compact Font Format Specification" , and #5177, .I "The Type 2 Charstring Format" .LP .IR "OpenType Specification" , Version 1.4 .LP .IR "A Directory Structure for TeX Files" , http://www.tug.org/tds/ .LP .IR "Kpathsea: A library for path searching" , http://www.tug.org/kpathsea/ .LP Sivan Toledo, .IR "Exploiting Rich Fonts" , TUGboat 21(2), 2000, http://www.tug.org/TUGboat/Articles/tb21-2/tb67tole.pdf .LP Michel Goossens, Frank Mittelbach, and Alexander Samarin, .IR "The LaTeX Companion" (for information on the .fd file format) .LP Adobe Systems, "Unicode and Glyph Names". Refers to the glyphlist.txt file used to translate glyph names to Unicode code points. http://partners.adobe.com/public/developer/opentype/index_glyph.html ' .SH AUTHOR Eddie Kohler (ekohler@gmail.com) .PP Thanks to Karl Berry, Marco Kuhlmann, Adam Lindsay, Bruce D'Arcus, Thomas Esser, Claire Connelly, Nelson H.F. Beebe, and Ryuji Suzuki for suggestions, bug reports, and help. Particular thanks to Achim Blumensath and Michael Zedler for suggestions and patches, some of them extensive. lcdf-typetools-2.108/missing0000755000175000017500000001533012732752553013031 00000000000000#! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2013-10-28.13; # UTC # Copyright (C) 1996-2014 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=http://www.perl.org/ flex_URL=http://flex.sourceforge.net/ gnu_software_URL=http://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: lcdf-typetools-2.108/Makefile.am0000664000175000017500000000611312732752520013461 00000000000000## Process this file with automake to produce Makefile.in AUTOMAKE_OPTIONS = foreign SUBDIRS = liblcdf libefont @SELECTED_SUBDIRS@ DIST_SUBDIRS = liblcdf libefont cfftot1 mmafm mmpfb otfinfo otftotfm \ t1dotlessj t1lint t1rawafm t1reencode t1testpage ttftotype42 EXTRA_DIST = \ ONEWS README.md NEWS.md \ lcdf-typetools.spec \ include/config.h \ include/lcdf/bezier.hh \ include/lcdf/clp.h \ include/lcdf/error.hh \ include/lcdf/filename.hh \ include/lcdf/globmatch.hh \ include/lcdf/hashcode.hh \ include/lcdf/hashmap.hh include/lcdf/hashmap.cc \ include/lcdf/inttypes.h \ include/lcdf/landmark.hh \ include/lcdf/md5.h \ include/lcdf/permstr.hh \ include/lcdf/point.hh \ include/lcdf/slurper.hh \ include/lcdf/straccum.hh \ include/lcdf/string.hh \ include/lcdf/strtonum.h \ include/lcdf/transform.hh \ include/lcdf/vector.hh include/lcdf/vector.cc \ include/efont/afm.hh \ include/efont/afmparse.hh \ include/efont/afmw.hh \ include/efont/amfm.hh \ include/efont/cff.hh \ include/efont/encoding.hh \ include/efont/findmet.hh \ include/efont/metrics.hh \ include/efont/otf.hh \ include/efont/otfcmap.hh \ include/efont/otfdata.hh \ include/efont/otfgpos.hh \ include/efont/otfgsub.hh \ include/efont/otfname.hh \ include/efont/otfos2.hh \ include/efont/otfpost.hh \ include/efont/pairop.hh \ include/efont/psres.hh \ include/efont/t1bounds.hh \ include/efont/t1cs.hh \ include/efont/t1csgen.hh \ include/efont/t1font.hh \ include/efont/t1interp.hh \ include/efont/t1item.hh \ include/efont/t1mm.hh \ include/efont/t1rw.hh \ include/efont/t1unparser.hh \ include/efont/ttfcs.hh \ include/efont/ttfhead.hh \ include/efont/ttfkern.hh \ glyphlist.txt \ texglyphlist.txt \ texglyphlist-g2u.txt \ 7t.enc glyphlist_DATA = glyphlist.txt texglyphlist.txt enc_DATA = 7t.enc liblcdf libefont: cd $@ && $(MAKE) libefont: liblcdf cfftot1 mmafm mmpfb otfinfo otftotfm t1dotlessj t1lint t1rawafm \ t1reencode t1testpage ttftotype42: liblcdf libefont cd $@ && $(MAKE) versionize: perl -pi -e 's/^\.ds V.*/.ds V $(VERSION)/;' $(srcdir)/cfftot1/cfftot1.1 $(srcdir)/mmafm/mmafm.1 $(srcdir)/mmpfb/mmpfb.1 $(srcdir)/otfinfo/otfinfo.1 $(srcdir)/otftotfm/otftotfm.1 $(srcdir)/t1dotlessj/t1dotlessj.1 $(srcdir)/t1lint/t1lint.1 $(srcdir)/t1rawafm/t1rawafm.1 $(srcdir)/t1reencode/t1reencode.1 $(srcdir)/t1testpage/t1testpage.1 $(srcdir)/ttftotype42/ttftotype42.1 perl -pi -e 's/^(\U$(PACKAGE)\E) [\d.ab]+$$/$$1 $(VERSION)/;' $(srcdir)/README.md perl -pi -e 's/^Version: [\d.ab]+$$/Version: $(VERSION)/;' $(srcdir)/lcdf-typetools.spec dist-hook: if test -f $(srcdir)/make-glyphtounicode.pl; then (cd $(srcdir); perl make-glyphtounicode.pl) > $(distdir)/glyphtounicode.tex; elif test -f $(srcdir)/glyphtounicode.tex; then cp $(srcdir)/glyphtounicode.tex $(distdir); fi $(srcdir)/glyphtounicode.tex: $(srcdir)/glyphlist.txt $(srcdir)/texglyphlist.txt $(srcdir)/texglyphlist-g2u.txt $(srcdir)/make-glyphtounicode.pl cd $(srcdir); perl make-glyphtounicode.pl > glyphtounicode.tex .PHONY: rpm liblcdf libefont cfftot1 mmafm mmpfb otfinfo otftotfm t1dotlessj t1lint t1rawafm t1reencode t1testpage ttftotype42 lcdf-typetools-2.108/texglyphlist-g2u.txt0000664000175000017500000006013112732752520015421 00000000000000# lcdf-typetools texglyphlist-g2u.txt, Version 2.95 # Contents: Overrides to glyphlist.txt and texglyphlist.txt used to # generate glyphtounicode.tex, which maps glyphs to searchable Unicode # code points. # -- # -- Map common ligatures to their components. # -- ff;0066 0066 ffi;0066 0066 0069 ffl;0066 0066 006C fi;0066 0069 fl;0066 006C longst;017F 0074 st;0073 0074 # -- # -- texglyphlist.txt overrides /heart, /diamond, /phi, and /phi1 to their # -- more typical meanings in encoding files meant for TeX: /heart and # -- /diamond are outline, not solid; /phi is straight; /phi1 is loopy. These # -- overrides are not appropriate for glyphtounicode.tex, which can apply to # -- any font. Newer fonts apply the AGL glyph shapes to these names. But we # -- can provide font-specific overrides for fonts commonly used with TeX. # -- diamond;2666 heart;2665 phi;03C6 phi1;03D5 tfm:lmmi5/phi;03D5 tfm:lmmi5/phi1;03C6 tfm:lmmi6/phi;03D5 tfm:lmmi6/phi1;03C6 tfm:lmmi7/phi;03D5 tfm:lmmi7/phi1;03C6 tfm:lmmi8/phi;03D5 tfm:lmmi8/phi1;03C6 tfm:lmmi9/phi;03D5 tfm:lmmi9/phi1;03C6 tfm:lmmi10/phi;03D5 tfm:lmmi10/phi1;03C6 tfm:lmmi12/phi;03D5 tfm:lmmi12/phi1;03C6 tfm:lmmib5/phi;03D5 tfm:lmmib5/phi1;03C6 tfm:lmmib7/phi;03D5 tfm:lmmib7/phi1;03C6 tfm:lmmib10/phi;03D5 tfm:lmmib10/phi1;03C6 tfm:lmbsy5/diamond;2662 tfm:lmbsy5/heart;2661 tfm:lmbsy7/diamond;2662 tfm:lmbsy7/heart;2661 tfm:lmbsy10/diamond;2662 tfm:lmbsy10/heart;2661 tfm:lmsy5/diamond;2662 tfm:lmsy5/heart;2661 tfm:lmsy6/diamond;2662 tfm:lmsy6/heart;2661 tfm:lmsy7/diamond;2662 tfm:lmsy7/heart;2661 tfm:lmsy8/diamond;2662 tfm:lmsy8/heart;2661 tfm:lmsy9/diamond;2662 tfm:lmsy9/heart;2661 tfm:lmsy10/diamond;2662 tfm:lmsy10/heart;2661 tfm:cmbsy10/diamond;2662 tfm:cmbsy10/heart;2661 tfm:cmbsy5/diamond;2662 tfm:cmbsy5/heart;2661 tfm:cmbsy6/diamond;2662 tfm:cmbsy6/heart;2661 tfm:cmbsy7/diamond;2662 tfm:cmbsy7/heart;2661 tfm:cmbsy8/diamond;2662 tfm:cmbsy8/heart;2661 tfm:cmbsy9/diamond;2662 tfm:cmbsy9/heart;2661 tfm:cmmi10/phi1;03C6 tfm:cmmi10/phi;03D5 tfm:cmmi12/phi1;03C6 tfm:cmmi12/phi;03D5 tfm:cmmi5/phi1;03C6 tfm:cmmi5/phi;03D5 tfm:cmmi6/phi1;03C6 tfm:cmmi6/phi;03D5 tfm:cmmi7/phi1;03C6 tfm:cmmi7/phi;03D5 tfm:cmmi8/phi1;03C6 tfm:cmmi8/phi;03D5 tfm:cmmi9/phi1;03C6 tfm:cmmi9/phi;03D5 tfm:cmmib10/phi1;03C6 tfm:cmmib10/phi;03D5 tfm:cmmib5/phi1;03C6 tfm:cmmib5/phi;03D5 tfm:cmmib6/phi1;03C6 tfm:cmmib6/phi;03D5 tfm:cmmib7/phi1;03C6 tfm:cmmib7/phi;03D5 tfm:cmmib8/phi1;03C6 tfm:cmmib8/phi;03D5 tfm:cmmib9/phi1;03C6 tfm:cmmib9/phi;03D5 tfm:cmsy10/diamond;2662 tfm:cmsy10/heart;2661 tfm:cmsy10/heart;2661 tfm:cmsy5/heart;2661 tfm:cmsy6/diamond;2662 tfm:cmsy6/heart;2661 tfm:cmsy7/diamond;2662 tfm:cmsy7/heart;2661 tfm:cmsy8/diamond;2662 tfm:cmsy8/heart;2661 tfm:cmsy9/diamond;2662 tfm:cmsy9/heart;2661 tfm:eurb10/phi1;03C6 tfm:eurb10/phi;03D5 tfm:eurb5/phi1;03C6 tfm:eurb5/phi;03D5 tfm:eurb6/phi1;03C6 tfm:eurb6/phi;03D5 tfm:eurb7/phi1;03C6 tfm:eurb7/phi;03D5 tfm:eurb8/phi1;03C6 tfm:eurb8/phi;03D5 tfm:eurb9/phi1;03C6 tfm:eurb9/phi;03D5 tfm:eurm10/phi1;03C6 tfm:eurm10/phi;03D5 tfm:eurm5/phi1;03C6 tfm:eurm5/phi;03D5 tfm:eurm6/phi1;03C6 tfm:eurm6/phi;03D5 tfm:eurm7/phi1;03C6 tfm:eurm7/phi;03D5 tfm:eurm8/phi1;03C6 tfm:eurm8/phi;03D5 tfm:eurm9/phi1;03C6 tfm:eurm9/phi;03D5 tfm:msam10/diamond;2662 tfm:msam5/diamond;2662 tfm:msam6/diamond;2662 tfm:msam7/diamond;2662 tfm:msam8/diamond;2662 tfm:msam9/diamond;2662 tfm:fplmbi/phi1;03C6 tfm:fplmbi/phi;03D5 tfm:fplmri/phi1;03C6 tfm:fplmri/phi;03D5 tfm:pxbmia/phi1;03C6 tfm:pxbmia/phi;03D5 tfm:pxbsy/diamond;2662 tfm:pxbsy/heart;2661 tfm:pxbsya/diamond;2662 tfm:pxmia/phi1;03C6 tfm:pxmia/phi;03D5 tfm:pxsy/diamond;2662 tfm:pxsy/heart;2661 tfm:pxsya/diamond;2662 tfm:rpxbmi/phi1;03C6 tfm:rpxbmi/phi;03D5 tfm:rpxmi/phi1;03C6 tfm:rpxmi/phi;03D5 tfm:rtxbmi/phi1;03C6 tfm:rtxbmi/phi;03D5 tfm:rtxmi/phi1;03C6 tfm:rtxmi/phi;03D5 tfm:txbmia/phi1;03C6 tfm:txbmia/phi;03D5 tfm:txbsy/diamond;2662 tfm:txbsy/heart;2661 tfm:txbsya/diamond;2662 tfm:txmia/phi1;03C6 tfm:txmia/phi;03D5 tfm:txsy/diamond;2662 tfm:txsy/heart;2661 tfm:txsya/diamond;2662 # -- # -- PDF searching works best if we map small capitals to lower case, not # -- private use code points as in glyphlist.txt. # -- AEsmall;00E6 Aacutesmall;00E1 Acircumflexsmall;00E2 Acute;00B4 Acutesmall;00B4 Adieresissmall;00E4 Agravesmall;00E0 Aringsmall;00E5 Asmall;0061 Atildesmall;00E3 Brevesmall;02D8 Bsmall;0062 Caron;02C7 Caronsmall;02C7 Ccedillasmall;00E7 Cedillasmall;00B8 Circumflexsmall;02C6 Csmall;0063 Dieresis;00A8 DieresisAcute;F6CC DieresisGrave;F6CD Dieresissmall;00A8 Dotaccentsmall;02D9 Dsmall;0064 Eacutesmall;00E9 Ecircumflexsmall;00EA Edieresissmall;00EB Egravesmall;00E8 Esmall;0065 Ethsmall;00F0 Fsmall;0066 Grave;0060 Gravesmall;0060 Gsmall;0067 Hsmall;0068 Hungarumlaut;02DD Hungarumlautsmall;02DD Iacutesmall;00ED Icircumflexsmall;00EE Idieresissmall;00EF Igravesmall;00EC Ismall;0069 Jsmall;006A Ksmall;006B LL;004C 004C Lslashsmall;0142 Lsmall;006C Macron;00AF Macronsmall;00AF Msmall;006D Nsmall;006E Ntildesmall;00F1 OEsmall;0153 Oacutesmall;00F3 Ocircumflexsmall;00F4 Odieresissmall;00F6 Ogoneksmall;02DB Ogravesmall;00F2 Oslashsmall;00F8 Osmall;006F Otildesmall;00F5 Psmall;0070 Qsmall;0071 Ringsmall;02DA Rsmall;0072 Scaronsmall;0161 Ssmall;0073 Thornsmall;00FE Tildesmall;02DC Tsmall;0074 Uacutesmall;00FA Ucircumflexsmall;00FB Udieresissmall;00FC Ugravesmall;00F9 Usmall;0075 Vsmall;0076 Wsmall;0077 Xsmall;0078 Yacutesmall;00FD Ydieresissmall;00FF Ysmall;0079 Zcaronsmall;017E Zsmall;007A # afii10063;F6C4 # afii10064;F6C5 # afii10192;F6C6 # afii10831;F6C7 # afii10832;F6C8 ampersandsmall;0026 # apple;F8FF # arrowhorizex;F8E7 # arrowvertex;F8E6 asuperior;0061 # braceex;F8F4 # braceleftbt;F8F3 # braceleftmid;F8F2 # bracelefttp;F8F1 # bracerightbt;F8FE # bracerightmid;F8FD # bracerighttp;F8FC # bracketleftbt;F8F0 # bracketleftex;F8EF # bracketlefttp;F8EE # bracketrightbt;F8FB # bracketrightex;F8FA # bracketrighttp;F8F9 bsuperior;0062 centinferior;00A2 centoldstyle;00A2 centsuperior;00A2 # commaaccent;F6C3 commainferior;002C commasuperior;002C copyrightsans;00A9 copyrightserif;00A9 cyrBreve;02D8 cyrFlex;00A0 0311 cyrbreve;02D8 cyrflex;00A0 0311 dblGrave;00A0 030F dblgrave;00A0 030F dieresisacute;00A0 0308 0301 dieresisgrave;00A0 0308 0300 dollarinferior;0024 dollaroldstyle;0024 dollarsuperior;0024 dotlessj;0237 dsuperior;0064 eightoldstyle;0038 esuperior;0065 exclamdownsmall;00A1 exclamsmall;0021 fiveoldstyle;0035 fouroldstyle;0034 hypheninferior;002D hyphensuperior;002D # integralex;F8F5 isuperior;0069 ll;006C 006C lsuperior;006C # maichattawalowleftthai;F895 # maichattawalowrightthai;F894 # maichattawaupperleftthai;F893 # maieklowleftthai;F88C # maieklowrightthai;F88B # maiekupperleftthai;F88A # maihanakatleftthai;F884 # maitaikhuleftthai;F889 # maitholowleftthai;F88F # maitholowrightthai;F88E # maithoupperleftthai;F88D # maitrilowleftthai;F892 # maitrilowrightthai;F891 # maitriupperleftthai;F890 msuperior;006D # nikhahitleftthai;F899 nineoldstyle;0039 onefitted;0031 oneoldstyle;0031 osuperior;006F # parenleftbt;F8ED # parenleftex;F8EC # parenlefttp;F8EB # parenrightbt;F8F8 # parenrightex;F8F7 # parenrighttp;F8F6 periodinferior;002E periodsuperior;002E questiondownsmall;00BF questionsmall;003F # radicalex;F8E5 registersans;00AE registerserif;00AE rsuperior;0072 rupiah;20A8 # saraiileftthai;F886 # saraileftthai;F885 # saraueeleftthai;F888 # saraueleftthai;F887 sevenoldstyle;0037 sixoldstyle;0036 ssuperior;0073 # thanthakhatlowleftthai;F898 # thanthakhatlowrightthai;F897 # thanthakhatupperleftthai;F896 threeoldstyle;0033 # threequartersemdash;F6DE trademarksans;2122 trademarkserif;2122 tsuperior;0074 twooldstyle;0032 zerooldstyle;0030 FFsmall;0066 0066 FFIsmall;0066 0066 0069 FFLsmall;0066 0066 006C FIsmall;0066 0069 FLsmall;0066 006C Germandblssmall;0073 0073 SSsmall;0073 0073 # -- # -- These character names are used in Zapf-Dingbats. # -- The encodings differ from Adobe's zdingbat.txt table version 0.2, # -- updated 30 March 1999, in that it does not use private use code points. # -- tfm:pzdr/a1;2701 tfm:pzdr/a2;2702 tfm:pzdr/a3;2704 tfm:pzdr/a4;260E tfm:pzdr/a5;2706 tfm:pzdr/a6;271D tfm:pzdr/a7;271E tfm:pzdr/a8;271F tfm:pzdr/a9;2720 tfm:pzdr/a10;2721 tfm:pzdr/a11;261B tfm:pzdr/a12;261E tfm:pzdr/a13;270C tfm:pzdr/a14;270D tfm:pzdr/a15;270E tfm:pzdr/a16;270F tfm:pzdr/a17;2711 tfm:pzdr/a18;2712 tfm:pzdr/a19;2713 tfm:pzdr/a20;2714 tfm:pzdr/a21;2715 tfm:pzdr/a22;2716 tfm:pzdr/a23;2717 tfm:pzdr/a24;2718 tfm:pzdr/a25;2719 tfm:pzdr/a26;271A tfm:pzdr/a27;271B tfm:pzdr/a28;271C tfm:pzdr/a29;2722 tfm:pzdr/a30;2723 tfm:pzdr/a31;2724 tfm:pzdr/a32;2725 tfm:pzdr/a33;2726 tfm:pzdr/a34;2727 tfm:pzdr/a35;2605 tfm:pzdr/a36;2729 tfm:pzdr/a37;272A tfm:pzdr/a38;272B tfm:pzdr/a39;272C tfm:pzdr/a40;272D tfm:pzdr/a41;272E tfm:pzdr/a42;272F tfm:pzdr/a43;2730 tfm:pzdr/a44;2731 tfm:pzdr/a45;2732 tfm:pzdr/a46;2733 tfm:pzdr/a47;2734 tfm:pzdr/a48;2735 tfm:pzdr/a49;2736 tfm:pzdr/a50;2737 tfm:pzdr/a51;2738 tfm:pzdr/a52;2739 tfm:pzdr/a53;273A tfm:pzdr/a54;273B tfm:pzdr/a55;273C tfm:pzdr/a56;273D tfm:pzdr/a57;273E tfm:pzdr/a58;273F tfm:pzdr/a59;2740 tfm:pzdr/a60;2741 tfm:pzdr/a61;2742 tfm:pzdr/a62;2743 tfm:pzdr/a63;2744 tfm:pzdr/a64;2745 tfm:pzdr/a65;2746 tfm:pzdr/a66;2747 tfm:pzdr/a67;2748 tfm:pzdr/a68;2749 tfm:pzdr/a69;274A tfm:pzdr/a70;274B tfm:pzdr/a71;25CF tfm:pzdr/a72;274D tfm:pzdr/a73;25A0 tfm:pzdr/a74;274F tfm:pzdr/a75;2751 tfm:pzdr/a76;25B2 tfm:pzdr/a77;25BC tfm:pzdr/a78;25C6 tfm:pzdr/a79;2756 tfm:pzdr/a81;25D7 tfm:pzdr/a82;2758 tfm:pzdr/a83;2759 tfm:pzdr/a84;275A tfm:pzdr/a85;276F tfm:pzdr/a86;2771 tfm:pzdr/a87;2772 tfm:pzdr/a88;2773 tfm:pzdr/a89;2768 tfm:pzdr/a90;2769 tfm:pzdr/a91;276C tfm:pzdr/a92;276D tfm:pzdr/a93;276A tfm:pzdr/a94;276B tfm:pzdr/a95;2774 tfm:pzdr/a96;2775 tfm:pzdr/a97;275B tfm:pzdr/a98;275C tfm:pzdr/a99;275D tfm:pzdr/a100;275E tfm:pzdr/a101;2761 tfm:pzdr/a102;2762 tfm:pzdr/a103;2763 tfm:pzdr/a104;2764 tfm:pzdr/a105;2710 tfm:pzdr/a106;2765 tfm:pzdr/a107;2766 tfm:pzdr/a108;2767 tfm:pzdr/a109;2660 tfm:pzdr/a110;2665 tfm:pzdr/a111;2666 tfm:pzdr/a112;2663 tfm:pzdr/a117;2709 tfm:pzdr/a118;2708 tfm:pzdr/a119;2707 tfm:pzdr/a120;2460 tfm:pzdr/a121;2461 tfm:pzdr/a122;2462 tfm:pzdr/a123;2463 tfm:pzdr/a124;2464 tfm:pzdr/a125;2465 tfm:pzdr/a126;2466 tfm:pzdr/a127;2467 tfm:pzdr/a128;2468 tfm:pzdr/a129;2469 tfm:pzdr/a130;2776 tfm:pzdr/a131;2777 tfm:pzdr/a132;2778 tfm:pzdr/a133;2779 tfm:pzdr/a134;277A tfm:pzdr/a135;277B tfm:pzdr/a136;277C tfm:pzdr/a137;277D tfm:pzdr/a138;277E tfm:pzdr/a139;277F tfm:pzdr/a140;2780 tfm:pzdr/a141;2781 tfm:pzdr/a142;2782 tfm:pzdr/a143;2783 tfm:pzdr/a144;2784 tfm:pzdr/a145;2785 tfm:pzdr/a146;2786 tfm:pzdr/a147;2787 tfm:pzdr/a148;2788 tfm:pzdr/a149;2789 tfm:pzdr/a150;278A tfm:pzdr/a151;278B tfm:pzdr/a152;278C tfm:pzdr/a153;278D tfm:pzdr/a154;278E tfm:pzdr/a155;278F tfm:pzdr/a156;2790 tfm:pzdr/a157;2791 tfm:pzdr/a158;2792 tfm:pzdr/a159;2793 tfm:pzdr/a160;2794 tfm:pzdr/a161;2192 tfm:pzdr/a162;27A3 tfm:pzdr/a163;2194 tfm:pzdr/a164;2195 tfm:pzdr/a165;2799 tfm:pzdr/a166;279B tfm:pzdr/a167;279C tfm:pzdr/a168;279D tfm:pzdr/a169;279E tfm:pzdr/a170;279F tfm:pzdr/a171;27A0 tfm:pzdr/a172;27A1 tfm:pzdr/a173;27A2 tfm:pzdr/a174;27A4 tfm:pzdr/a175;27A5 tfm:pzdr/a176;27A6 tfm:pzdr/a177;27A7 tfm:pzdr/a178;27A8 tfm:pzdr/a179;27A9 tfm:pzdr/a180;27AB tfm:pzdr/a181;27AD tfm:pzdr/a182;27AF tfm:pzdr/a183;27B2 tfm:pzdr/a184;27B3 tfm:pzdr/a185;27B5 tfm:pzdr/a186;27B8 tfm:pzdr/a187;27BA tfm:pzdr/a188;27BB tfm:pzdr/a189;27BC tfm:pzdr/a190;27BD tfm:pzdr/a191;27BE tfm:pzdr/a192;279A tfm:pzdr/a193;27AA tfm:pzdr/a194;27B6 tfm:pzdr/a195;27B9 tfm:pzdr/a196;2798 tfm:pzdr/a197;27B4 tfm:pzdr/a198;27B7 tfm:pzdr/a199;27AC tfm:pzdr/a200;27AE tfm:pzdr/a201;27B1 tfm:pzdr/a202;2703 tfm:pzdr/a203;2750 tfm:pzdr/a204;2752 tfm:pzdr/a205;276E tfm:pzdr/a206;2770 tfm:rpzdr/a1;2701 tfm:rpzdr/a2;2702 tfm:rpzdr/a3;2704 tfm:rpzdr/a4;260E tfm:rpzdr/a5;2706 tfm:rpzdr/a6;271D tfm:rpzdr/a7;271E tfm:rpzdr/a8;271F tfm:rpzdr/a9;2720 tfm:rpzdr/a10;2721 tfm:rpzdr/a11;261B tfm:rpzdr/a12;261E tfm:rpzdr/a13;270C tfm:rpzdr/a14;270D tfm:rpzdr/a15;270E tfm:rpzdr/a16;270F tfm:rpzdr/a17;2711 tfm:rpzdr/a18;2712 tfm:rpzdr/a19;2713 tfm:rpzdr/a20;2714 tfm:rpzdr/a21;2715 tfm:rpzdr/a22;2716 tfm:rpzdr/a23;2717 tfm:rpzdr/a24;2718 tfm:rpzdr/a25;2719 tfm:rpzdr/a26;271A tfm:rpzdr/a27;271B tfm:rpzdr/a28;271C tfm:rpzdr/a29;2722 tfm:rpzdr/a30;2723 tfm:rpzdr/a31;2724 tfm:rpzdr/a32;2725 tfm:rpzdr/a33;2726 tfm:rpzdr/a34;2727 tfm:rpzdr/a35;2605 tfm:rpzdr/a36;2729 tfm:rpzdr/a37;272A tfm:rpzdr/a38;272B tfm:rpzdr/a39;272C tfm:rpzdr/a40;272D tfm:rpzdr/a41;272E tfm:rpzdr/a42;272F tfm:rpzdr/a43;2730 tfm:rpzdr/a44;2731 tfm:rpzdr/a45;2732 tfm:rpzdr/a46;2733 tfm:rpzdr/a47;2734 tfm:rpzdr/a48;2735 tfm:rpzdr/a49;2736 tfm:rpzdr/a50;2737 tfm:rpzdr/a51;2738 tfm:rpzdr/a52;2739 tfm:rpzdr/a53;273A tfm:rpzdr/a54;273B tfm:rpzdr/a55;273C tfm:rpzdr/a56;273D tfm:rpzdr/a57;273E tfm:rpzdr/a58;273F tfm:rpzdr/a59;2740 tfm:rpzdr/a60;2741 tfm:rpzdr/a61;2742 tfm:rpzdr/a62;2743 tfm:rpzdr/a63;2744 tfm:rpzdr/a64;2745 tfm:rpzdr/a65;2746 tfm:rpzdr/a66;2747 tfm:rpzdr/a67;2748 tfm:rpzdr/a68;2749 tfm:rpzdr/a69;274A tfm:rpzdr/a70;274B tfm:rpzdr/a71;25CF tfm:rpzdr/a72;274D tfm:rpzdr/a73;25A0 tfm:rpzdr/a74;274F tfm:rpzdr/a75;2751 tfm:rpzdr/a76;25B2 tfm:rpzdr/a77;25BC tfm:rpzdr/a78;25C6 tfm:rpzdr/a79;2756 tfm:rpzdr/a81;25D7 tfm:rpzdr/a82;2758 tfm:rpzdr/a83;2759 tfm:rpzdr/a84;275A tfm:rpzdr/a85;276F tfm:rpzdr/a86;2771 tfm:rpzdr/a87;2772 tfm:rpzdr/a88;2773 tfm:rpzdr/a89;2768 tfm:rpzdr/a90;2769 tfm:rpzdr/a91;276C tfm:rpzdr/a92;276D tfm:rpzdr/a93;276A tfm:rpzdr/a94;276B tfm:rpzdr/a95;2774 tfm:rpzdr/a96;2775 tfm:rpzdr/a97;275B tfm:rpzdr/a98;275C tfm:rpzdr/a99;275D tfm:rpzdr/a100;275E tfm:rpzdr/a101;2761 tfm:rpzdr/a102;2762 tfm:rpzdr/a103;2763 tfm:rpzdr/a104;2764 tfm:rpzdr/a105;2710 tfm:rpzdr/a106;2765 tfm:rpzdr/a107;2766 tfm:rpzdr/a108;2767 tfm:rpzdr/a109;2660 tfm:rpzdr/a110;2665 tfm:rpzdr/a111;2666 tfm:rpzdr/a112;2663 tfm:rpzdr/a117;2709 tfm:rpzdr/a118;2708 tfm:rpzdr/a119;2707 tfm:rpzdr/a120;2460 tfm:rpzdr/a121;2461 tfm:rpzdr/a122;2462 tfm:rpzdr/a123;2463 tfm:rpzdr/a124;2464 tfm:rpzdr/a125;2465 tfm:rpzdr/a126;2466 tfm:rpzdr/a127;2467 tfm:rpzdr/a128;2468 tfm:rpzdr/a129;2469 tfm:rpzdr/a130;2776 tfm:rpzdr/a131;2777 tfm:rpzdr/a132;2778 tfm:rpzdr/a133;2779 tfm:rpzdr/a134;277A tfm:rpzdr/a135;277B tfm:rpzdr/a136;277C tfm:rpzdr/a137;277D tfm:rpzdr/a138;277E tfm:rpzdr/a139;277F tfm:rpzdr/a140;2780 tfm:rpzdr/a141;2781 tfm:rpzdr/a142;2782 tfm:rpzdr/a143;2783 tfm:rpzdr/a144;2784 tfm:rpzdr/a145;2785 tfm:rpzdr/a146;2786 tfm:rpzdr/a147;2787 tfm:rpzdr/a148;2788 tfm:rpzdr/a149;2789 tfm:rpzdr/a150;278A tfm:rpzdr/a151;278B tfm:rpzdr/a152;278C tfm:rpzdr/a153;278D tfm:rpzdr/a154;278E tfm:rpzdr/a155;278F tfm:rpzdr/a156;2790 tfm:rpzdr/a157;2791 tfm:rpzdr/a158;2792 tfm:rpzdr/a159;2793 tfm:rpzdr/a160;2794 tfm:rpzdr/a161;2192 tfm:rpzdr/a162;27A3 tfm:rpzdr/a163;2194 tfm:rpzdr/a164;2195 tfm:rpzdr/a165;2799 tfm:rpzdr/a166;279B tfm:rpzdr/a167;279C tfm:rpzdr/a168;279D tfm:rpzdr/a169;279E tfm:rpzdr/a170;279F tfm:rpzdr/a171;27A0 tfm:rpzdr/a172;27A1 tfm:rpzdr/a173;27A2 tfm:rpzdr/a174;27A4 tfm:rpzdr/a175;27A5 tfm:rpzdr/a176;27A6 tfm:rpzdr/a177;27A7 tfm:rpzdr/a178;27A8 tfm:rpzdr/a179;27A9 tfm:rpzdr/a180;27AB tfm:rpzdr/a181;27AD tfm:rpzdr/a182;27AF tfm:rpzdr/a183;27B2 tfm:rpzdr/a184;27B3 tfm:rpzdr/a185;27B5 tfm:rpzdr/a186;27B8 tfm:rpzdr/a187;27BA tfm:rpzdr/a188;27BB tfm:rpzdr/a189;27BC tfm:rpzdr/a190;27BD tfm:rpzdr/a191;27BE tfm:rpzdr/a192;279A tfm:rpzdr/a193;27AA tfm:rpzdr/a194;27B6 tfm:rpzdr/a195;27B9 tfm:rpzdr/a196;2798 tfm:rpzdr/a197;27B4 tfm:rpzdr/a198;27B7 tfm:rpzdr/a199;27AC tfm:rpzdr/a200;27AE tfm:rpzdr/a201;27B1 tfm:rpzdr/a202;2703 tfm:rpzdr/a203;2750 tfm:rpzdr/a204;2752 tfm:rpzdr/a205;276E tfm:rpzdr/a206;2770 tfm:zd/a1;2701 tfm:zd/a2;2702 tfm:zd/a3;2704 tfm:zd/a4;260E tfm:zd/a5;2706 tfm:zd/a6;271D tfm:zd/a7;271E tfm:zd/a8;271F tfm:zd/a9;2720 tfm:zd/a10;2721 tfm:zd/a11;261B tfm:zd/a12;261E tfm:zd/a13;270C tfm:zd/a14;270D tfm:zd/a15;270E tfm:zd/a16;270F tfm:zd/a17;2711 tfm:zd/a18;2712 tfm:zd/a19;2713 tfm:zd/a20;2714 tfm:zd/a21;2715 tfm:zd/a22;2716 tfm:zd/a23;2717 tfm:zd/a24;2718 tfm:zd/a25;2719 tfm:zd/a26;271A tfm:zd/a27;271B tfm:zd/a28;271C tfm:zd/a29;2722 tfm:zd/a30;2723 tfm:zd/a31;2724 tfm:zd/a32;2725 tfm:zd/a33;2726 tfm:zd/a34;2727 tfm:zd/a35;2605 tfm:zd/a36;2729 tfm:zd/a37;272A tfm:zd/a38;272B tfm:zd/a39;272C tfm:zd/a40;272D tfm:zd/a41;272E tfm:zd/a42;272F tfm:zd/a43;2730 tfm:zd/a44;2731 tfm:zd/a45;2732 tfm:zd/a46;2733 tfm:zd/a47;2734 tfm:zd/a48;2735 tfm:zd/a49;2736 tfm:zd/a50;2737 tfm:zd/a51;2738 tfm:zd/a52;2739 tfm:zd/a53;273A tfm:zd/a54;273B tfm:zd/a55;273C tfm:zd/a56;273D tfm:zd/a57;273E tfm:zd/a58;273F tfm:zd/a59;2740 tfm:zd/a60;2741 tfm:zd/a61;2742 tfm:zd/a62;2743 tfm:zd/a63;2744 tfm:zd/a64;2745 tfm:zd/a65;2746 tfm:zd/a66;2747 tfm:zd/a67;2748 tfm:zd/a68;2749 tfm:zd/a69;274A tfm:zd/a70;274B tfm:zd/a71;25CF tfm:zd/a72;274D tfm:zd/a73;25A0 tfm:zd/a74;274F tfm:zd/a75;2751 tfm:zd/a76;25B2 tfm:zd/a77;25BC tfm:zd/a78;25C6 tfm:zd/a79;2756 tfm:zd/a81;25D7 tfm:zd/a82;2758 tfm:zd/a83;2759 tfm:zd/a84;275A tfm:zd/a85;276F tfm:zd/a86;2771 tfm:zd/a87;2772 tfm:zd/a88;2773 tfm:zd/a89;2768 tfm:zd/a90;2769 tfm:zd/a91;276C tfm:zd/a92;276D tfm:zd/a93;276A tfm:zd/a94;276B tfm:zd/a95;2774 tfm:zd/a96;2775 tfm:zd/a97;275B tfm:zd/a98;275C tfm:zd/a99;275D tfm:zd/a100;275E tfm:zd/a101;2761 tfm:zd/a102;2762 tfm:zd/a103;2763 tfm:zd/a104;2764 tfm:zd/a105;2710 tfm:zd/a106;2765 tfm:zd/a107;2766 tfm:zd/a108;2767 tfm:zd/a109;2660 tfm:zd/a110;2665 tfm:zd/a111;2666 tfm:zd/a112;2663 tfm:zd/a117;2709 tfm:zd/a118;2708 tfm:zd/a119;2707 tfm:zd/a120;2460 tfm:zd/a121;2461 tfm:zd/a122;2462 tfm:zd/a123;2463 tfm:zd/a124;2464 tfm:zd/a125;2465 tfm:zd/a126;2466 tfm:zd/a127;2467 tfm:zd/a128;2468 tfm:zd/a129;2469 tfm:zd/a130;2776 tfm:zd/a131;2777 tfm:zd/a132;2778 tfm:zd/a133;2779 tfm:zd/a134;277A tfm:zd/a135;277B tfm:zd/a136;277C tfm:zd/a137;277D tfm:zd/a138;277E tfm:zd/a139;277F tfm:zd/a140;2780 tfm:zd/a141;2781 tfm:zd/a142;2782 tfm:zd/a143;2783 tfm:zd/a144;2784 tfm:zd/a145;2785 tfm:zd/a146;2786 tfm:zd/a147;2787 tfm:zd/a148;2788 tfm:zd/a149;2789 tfm:zd/a150;278A tfm:zd/a151;278B tfm:zd/a152;278C tfm:zd/a153;278D tfm:zd/a154;278E tfm:zd/a155;278F tfm:zd/a156;2790 tfm:zd/a157;2791 tfm:zd/a158;2792 tfm:zd/a159;2793 tfm:zd/a160;2794 tfm:zd/a161;2192 tfm:zd/a162;27A3 tfm:zd/a163;2194 tfm:zd/a164;2195 tfm:zd/a165;2799 tfm:zd/a166;279B tfm:zd/a167;279C tfm:zd/a168;279D tfm:zd/a169;279E tfm:zd/a170;279F tfm:zd/a171;27A0 tfm:zd/a172;27A1 tfm:zd/a173;27A2 tfm:zd/a174;27A4 tfm:zd/a175;27A5 tfm:zd/a176;27A6 tfm:zd/a177;27A7 tfm:zd/a178;27A8 tfm:zd/a179;27A9 tfm:zd/a180;27AB tfm:zd/a181;27AD tfm:zd/a182;27AF tfm:zd/a183;27B2 tfm:zd/a184;27B3 tfm:zd/a185;27B5 tfm:zd/a186;27B8 tfm:zd/a187;27BA tfm:zd/a188;27BB tfm:zd/a189;27BC tfm:zd/a190;27BD tfm:zd/a191;27BE tfm:zd/a192;279A tfm:zd/a193;27AA tfm:zd/a194;27B6 tfm:zd/a195;27B9 tfm:zd/a196;2798 tfm:zd/a197;27B4 tfm:zd/a198;27B7 tfm:zd/a199;27AC tfm:zd/a200;27AE tfm:zd/a201;27B1 tfm:zd/a202;2703 tfm:zd/a203;2750 tfm:zd/a204;2752 tfm:zd/a205;276E tfm:zd/a206;2770 tfm:zpzdr-reversed/a1;2701 tfm:zpzdr-reversed/a2;2702 tfm:zpzdr-reversed/a3;2704 tfm:zpzdr-reversed/a4;260E tfm:zpzdr-reversed/a5;2706 tfm:zpzdr-reversed/a6;271D tfm:zpzdr-reversed/a7;271E tfm:zpzdr-reversed/a8;271F tfm:zpzdr-reversed/a9;2720 tfm:zpzdr-reversed/a10;2721 tfm:zpzdr-reversed/a11;261B tfm:zpzdr-reversed/a12;261E tfm:zpzdr-reversed/a13;270C tfm:zpzdr-reversed/a14;270D tfm:zpzdr-reversed/a15;270E tfm:zpzdr-reversed/a16;270F tfm:zpzdr-reversed/a17;2711 tfm:zpzdr-reversed/a18;2712 tfm:zpzdr-reversed/a19;2713 tfm:zpzdr-reversed/a20;2714 tfm:zpzdr-reversed/a21;2715 tfm:zpzdr-reversed/a22;2716 tfm:zpzdr-reversed/a23;2717 tfm:zpzdr-reversed/a24;2718 tfm:zpzdr-reversed/a25;2719 tfm:zpzdr-reversed/a26;271A tfm:zpzdr-reversed/a27;271B tfm:zpzdr-reversed/a28;271C tfm:zpzdr-reversed/a29;2722 tfm:zpzdr-reversed/a30;2723 tfm:zpzdr-reversed/a31;2724 tfm:zpzdr-reversed/a32;2725 tfm:zpzdr-reversed/a33;2726 tfm:zpzdr-reversed/a34;2727 tfm:zpzdr-reversed/a35;2605 tfm:zpzdr-reversed/a36;2729 tfm:zpzdr-reversed/a37;272A tfm:zpzdr-reversed/a38;272B tfm:zpzdr-reversed/a39;272C tfm:zpzdr-reversed/a40;272D tfm:zpzdr-reversed/a41;272E tfm:zpzdr-reversed/a42;272F tfm:zpzdr-reversed/a43;2730 tfm:zpzdr-reversed/a44;2731 tfm:zpzdr-reversed/a45;2732 tfm:zpzdr-reversed/a46;2733 tfm:zpzdr-reversed/a47;2734 tfm:zpzdr-reversed/a48;2735 tfm:zpzdr-reversed/a49;2736 tfm:zpzdr-reversed/a50;2737 tfm:zpzdr-reversed/a51;2738 tfm:zpzdr-reversed/a52;2739 tfm:zpzdr-reversed/a53;273A tfm:zpzdr-reversed/a54;273B tfm:zpzdr-reversed/a55;273C tfm:zpzdr-reversed/a56;273D tfm:zpzdr-reversed/a57;273E tfm:zpzdr-reversed/a58;273F tfm:zpzdr-reversed/a59;2740 tfm:zpzdr-reversed/a60;2741 tfm:zpzdr-reversed/a61;2742 tfm:zpzdr-reversed/a62;2743 tfm:zpzdr-reversed/a63;2744 tfm:zpzdr-reversed/a64;2745 tfm:zpzdr-reversed/a65;2746 tfm:zpzdr-reversed/a66;2747 tfm:zpzdr-reversed/a67;2748 tfm:zpzdr-reversed/a68;2749 tfm:zpzdr-reversed/a69;274A tfm:zpzdr-reversed/a70;274B tfm:zpzdr-reversed/a71;25CF tfm:zpzdr-reversed/a72;274D tfm:zpzdr-reversed/a73;25A0 tfm:zpzdr-reversed/a74;274F tfm:zpzdr-reversed/a75;2751 tfm:zpzdr-reversed/a76;25B2 tfm:zpzdr-reversed/a77;25BC tfm:zpzdr-reversed/a78;25C6 tfm:zpzdr-reversed/a79;2756 tfm:zpzdr-reversed/a81;25D7 tfm:zpzdr-reversed/a82;2758 tfm:zpzdr-reversed/a83;2759 tfm:zpzdr-reversed/a84;275A tfm:zpzdr-reversed/a85;276F tfm:zpzdr-reversed/a86;2771 tfm:zpzdr-reversed/a87;2772 tfm:zpzdr-reversed/a88;2773 tfm:zpzdr-reversed/a89;2768 tfm:zpzdr-reversed/a90;2769 tfm:zpzdr-reversed/a91;276C tfm:zpzdr-reversed/a92;276D tfm:zpzdr-reversed/a93;276A tfm:zpzdr-reversed/a94;276B tfm:zpzdr-reversed/a95;2774 tfm:zpzdr-reversed/a96;2775 tfm:zpzdr-reversed/a97;275B tfm:zpzdr-reversed/a98;275C tfm:zpzdr-reversed/a99;275D tfm:zpzdr-reversed/a100;275E tfm:zpzdr-reversed/a101;2761 tfm:zpzdr-reversed/a102;2762 tfm:zpzdr-reversed/a103;2763 tfm:zpzdr-reversed/a104;2764 tfm:zpzdr-reversed/a105;2710 tfm:zpzdr-reversed/a106;2765 tfm:zpzdr-reversed/a107;2766 tfm:zpzdr-reversed/a108;2767 tfm:zpzdr-reversed/a109;2660 tfm:zpzdr-reversed/a110;2665 tfm:zpzdr-reversed/a111;2666 tfm:zpzdr-reversed/a112;2663 tfm:zpzdr-reversed/a117;2709 tfm:zpzdr-reversed/a118;2708 tfm:zpzdr-reversed/a119;2707 tfm:zpzdr-reversed/a120;2460 tfm:zpzdr-reversed/a121;2461 tfm:zpzdr-reversed/a122;2462 tfm:zpzdr-reversed/a123;2463 tfm:zpzdr-reversed/a124;2464 tfm:zpzdr-reversed/a125;2465 tfm:zpzdr-reversed/a126;2466 tfm:zpzdr-reversed/a127;2467 tfm:zpzdr-reversed/a128;2468 tfm:zpzdr-reversed/a129;2469 tfm:zpzdr-reversed/a130;2776 tfm:zpzdr-reversed/a131;2777 tfm:zpzdr-reversed/a132;2778 tfm:zpzdr-reversed/a133;2779 tfm:zpzdr-reversed/a134;277A tfm:zpzdr-reversed/a135;277B tfm:zpzdr-reversed/a136;277C tfm:zpzdr-reversed/a137;277D tfm:zpzdr-reversed/a138;277E tfm:zpzdr-reversed/a139;277F tfm:zpzdr-reversed/a140;2780 tfm:zpzdr-reversed/a141;2781 tfm:zpzdr-reversed/a142;2782 tfm:zpzdr-reversed/a143;2783 tfm:zpzdr-reversed/a144;2784 tfm:zpzdr-reversed/a145;2785 tfm:zpzdr-reversed/a146;2786 tfm:zpzdr-reversed/a147;2787 tfm:zpzdr-reversed/a148;2788 tfm:zpzdr-reversed/a149;2789 tfm:zpzdr-reversed/a150;278A tfm:zpzdr-reversed/a151;278B tfm:zpzdr-reversed/a152;278C tfm:zpzdr-reversed/a153;278D tfm:zpzdr-reversed/a154;278E tfm:zpzdr-reversed/a155;278F tfm:zpzdr-reversed/a156;2790 tfm:zpzdr-reversed/a157;2791 tfm:zpzdr-reversed/a158;2792 tfm:zpzdr-reversed/a159;2793 tfm:zpzdr-reversed/a160;2794 tfm:zpzdr-reversed/a161;2192 tfm:zpzdr-reversed/a162;27A3 tfm:zpzdr-reversed/a163;2194 tfm:zpzdr-reversed/a164;2195 tfm:zpzdr-reversed/a165;2799 tfm:zpzdr-reversed/a166;279B tfm:zpzdr-reversed/a167;279C tfm:zpzdr-reversed/a168;279D tfm:zpzdr-reversed/a169;279E tfm:zpzdr-reversed/a170;279F tfm:zpzdr-reversed/a171;27A0 tfm:zpzdr-reversed/a172;27A1 tfm:zpzdr-reversed/a173;27A2 tfm:zpzdr-reversed/a174;27A4 tfm:zpzdr-reversed/a175;27A5 tfm:zpzdr-reversed/a176;27A6 tfm:zpzdr-reversed/a177;27A7 tfm:zpzdr-reversed/a178;27A8 tfm:zpzdr-reversed/a179;27A9 tfm:zpzdr-reversed/a180;27AB tfm:zpzdr-reversed/a181;27AD tfm:zpzdr-reversed/a182;27AF tfm:zpzdr-reversed/a183;27B2 tfm:zpzdr-reversed/a184;27B3 tfm:zpzdr-reversed/a185;27B5 tfm:zpzdr-reversed/a186;27B8 tfm:zpzdr-reversed/a187;27BA tfm:zpzdr-reversed/a188;27BB tfm:zpzdr-reversed/a189;27BC tfm:zpzdr-reversed/a190;27BD tfm:zpzdr-reversed/a191;27BE tfm:zpzdr-reversed/a192;279A tfm:zpzdr-reversed/a193;27AA tfm:zpzdr-reversed/a194;27B6 tfm:zpzdr-reversed/a195;27B9 tfm:zpzdr-reversed/a196;2798 tfm:zpzdr-reversed/a197;27B4 tfm:zpzdr-reversed/a198;27B7 tfm:zpzdr-reversed/a199;27AC tfm:zpzdr-reversed/a200;27AE tfm:zpzdr-reversed/a201;27B1 tfm:zpzdr-reversed/a202;2703 tfm:zpzdr-reversed/a203;2750 tfm:zpzdr-reversed/a204;2752 tfm:zpzdr-reversed/a205;276E tfm:zpzdr-reversed/a206;2770 lcdf-typetools-2.108/lcdf-typetools.spec0000644000175000017500000000543013423376706015256 00000000000000Summary: Programs to manipulate OpenType and multiple-master fonts Name: lcdf-typetools Version: 2.108 Copyright: GPL Vendor: Little Cambridgeport Design Factory Group: Utilities/Printing Source: %{name}-%{version}.tar.gz Buildroot: /var/tmp/%{name}-%{version}-buildroot Requires: tetex > 2.0 %description This package contains four tools for working with OpenType fonts: cfftot1 allows you to translate Compact Font Format (CFF) or PostScript-flavored OpenType fonts into PostScript Type 1 font format otfinfo reports information about OpenType fonts, such as the features they support and the contents of their ``size'' optical size option otftotfm allows you to create TeX font metrics and encodings for using OpenType fonts t1dotlessj creates a Type 1 font with a single character -- the dotless j corresponding to the specified design t1lint checks a Type 1 font for correctness (preliminary) t1reencode reencodes a Type 1 font, replacing its internal encoding with one you specify t1testpage creates a PostScript test page for a specified font file (preliminary) ttftotype42 creates a Type 42 wrapper for a TrueType or TrueType-flavored OpenType font. The package now includes programs for working with multiple-master fonts formerly distributed as mminstance. These tools allow you to use multiple-master fonts with programs that require single-master fonts (afm2tfm, ps2pk, fontinst, etc.). Both programs work fine with fonts that contain intermediate masters (e.g., Adobe Jenson MM and Adobe Kepler MM). mmafm creates an AFM (Adobe font metric) file corresponding to a single instance of a multiple-master font. It reads (and therefore requires) the AMFM and AFM files distributed with the font. mmpfb creates a normal, single-master font program that looks like an instance of a multiple-master font. It reads the multiple-master font program in PFA or PFB format. ## PREP %prep %setup -q ## BUILD %build %configure make ## PRE %pre ## POST %post ## INSTALL %install [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT make DESTDIR=$RPM_BUILD_ROOT install #make install all DESTDIR=%{buildroot} ## FILES %files %defattr(-,root,root) %doc NEWS ONEWS README %{_bindir}/cfftot1 %{_bindir}/mmafm %{_bindir}/mmpfb %{_bindir}/otfinfo %{_bindir}/otftotfm %{_bindir}/t1dotlessj %{_bindir}/t1lint %{_bindir}/t1reencode %{_bindir}/t1testpage %{_bindir}/ttftotype42 %{_mandir}/man*/* %{_datadir}/lcdf-typetools/* %changelog * Fri Aug 3 2007 Eddie Kohler - Updates. * Wed Sep 8 2004 Claire Connelly - 2.12-hmcmath.1 - Initial packaging. lcdf-typetools-2.108/ONEWS0000664000175000017500000003077312732752520012254 00000000000000Mminstance NEWS This file contains news relevant to the mmafm and mmpfb programs, which used to be distributed separately in the mminstance package. Version 1.50 20.Aug.2003 * As of version 1.50, mminstance is distributed as part of the lcdf-typetools package. Changes for versions 1.50 and up are listed in NEWS. Version 1.26.3 14.Aug.2003 * Library changes to attempt to satisfy more C++ compilers. Again massive thanks to Nelson H.F. Beebe, and new massive thanks to Fabrice Popineau. Version 1.26.2 13.Aug.2003 * Revert from '#include ' to '#include '. Version 1.26.1 11.Aug.2003 * 'uintptr_t' configury, and more template changes. Version 1.26 10.Aug.2003 * Further address build problems reported by Nelson Beebe. Version 1.25 7.Aug.2003 * Address build problems reported by Nelson H.F. Beebe. Version 1.24 30.Jul.2003 * Fix configure check for whether va_list is addressable. Ryan Murray found the bug; thanks hugely to Claire Connelly for testing resources. * Minor code restructuring. * mmpfb: --minimize is the default. * mmpfb: --minimize additionally forces some interpolated values to integers, specifically BlueValues, OtherBlues, FamilyBlues, FamilyOtherBlues, and BlueShift. Maybe this will avoid some problems people have had with embedding mmpfb-generated fonts and Acrobat 6. * Change rounding procedures. Now fonts generated on different platforms will likely not differ in rounding details. (What a difference 0.00001 makes!) Version 1.23 9.Jul.2003 * Add configure check for whether va_list is addressable. Thanks to Claire Connelly. Version 1.22 5.Jun.2003 * More template nonsense. Mea culpa to Melissa O'Neill and Claire Connelly. Version 1.21 4.Jun.2003 * GCC 3.3 would not link mminstance due to missing template instantiations. Moved templatei.cc into libefont.a to fix this. Reported by Melissa O'Neill . Version 1.20 26.Jan.2003 * mmafm: Fix bug with parsing intermediate-master files that made AJensonMM unusable. Reported by Fulko van Westrenen . Version 1.19 5.Jan.2003 * mmpfb: Previously, error introduced by the rounding process could build up over the length of a path, causing an anomaly when the path was closed. Now mmpfb compensates for rounding error, resulting in a path with better fidelity. * mmpfb: Add the `--minimize' option to minimize output fonts, allowing the X font server to load mmpfb-generated fonts. Problem with the X font server reported by Joerg Lippman . * mmpfb: Add placeholder subroutines to fill in any gaps in the subroutine array, which the X font server doesn't like (that IBM Type 1 code is bad!). Probably this should be optional, since it makes the font bigger. * mmpfb: Renumber subroutines consecutively. * mmpfb: Generate a new FullName as well as a new FontName. * Adapt to newer Automake and LCDF and Efont libraries. Version 1.18 5.Oct.2002 * Fix for compilation with newer C++ compilers. Version 1.17 30.Sep.2002 * Fix for NuevaMM-It: the ItalicAngle array was not being properly commented out. Reported by Thomas Wu . Version 1.16.3 17.Sep.2001 * Workaround for Mac OS X: its sscanf() function behaves incorrectly when a format string ends with ` %n'. Reported and patched by Melissa O'Neill . Version 1.16.2 6.Sep.2001 * Improvements so mminstance compiles on more platforms. Problems reported by Nelson H. F. Beebe . Version 1.16.1 15.Jul.2001 * Bug fix: more cleanups for newer GCCs. Reported by C. M. Connelly . Version 1.16 18.Jun.2001 * Bug fix: now newer C++ compilers will compile mminstance. Reported by Melissa O'Neill . Version 1.15.1 12.Aug.2000 * Don't use `-Wall' by default; old C++ compilers generate huge numbers of irrelevant warnings. Reported by Tom Kacvinsky . Version 1.15 12.Jul.2000 * mmpfb: Remove calls to nonexistent subroutines. (This was not actually a bug; the calls to nonexistent subroutines would never execute anyway. The font ITCGaramondMM-It had characters like `/question { A callsubr B callsubr }', where the `A' subroutine would either draw an entire character and call `endchar' -- so `B' would never get called -- or it would do nothing at all. Previous mmpfb versions would remove the `B' subroutine but keep the `B callsubr' call if the interpolated `A' called `endchar'.) Requested by Han The Thanh . * mmpfb: Removed warning about `strange othersubr commands'. Version 1.14 22.Jun.2000 * mmpfb: Fixed a bug with large UniqueID values. Reported by Sivan Toledo . * mmpfb: Support for interpolating BlueFuzz without any warnings. Version 1.13 16.Apr.2000 * mmpfb: Can handle synthetic fonts like TektonMM-Oblique. Requested by Melissa O'Neill . Version 1.12 5.Apr.2000 * mmpfb: Make sure to remove multiple master commands from hint replacement subroutines. Required another overhaul. Requested by Han The Thanh . Version 1.11 3.Apr.2000 * mmafm: Added `--kern-precision' option. Requested by Han The Thanh . * Bug fix: now mminstance can be compiled with recent versions of gcc. The error was a strange use of va_arg(). Reported by C. M. Connelly . Version 1.10 21.Feb.2000 * mmpfb: Comment out DesignVector, NormDesignVector, and WeightVector entries. Now Ghostscript 6.0's ps2pdf script will work with mmpfb-generated fonts. Change requested by Melissa O'Neill . Version 1.9 18.Jan.2000 * mmpfb: Bug fix in special callothersubrs code introduced in Version 1.8. This bug probably did not affect anyone. Version 1.8 10.Jan.2000 * mmpfb: Don't warn when encountering `BuildCharArray'. This shows up in some ITC multiple masters. Requested by Han The Thanh . * mmpfb: Handle special callothersubrs from ITC Garamond MM. This required big changes, but the code is cleaner now, and more likely to be right in future: best of both worlds. Requested by Han The Thanh . Version 1.7 30.Dec.1999 * mmpfb: Fixed bug where garbled encoding vectors could be produced. Patch sent in by Christopher League . * Bug fix: Some error messages used to cause assertion failures. Version 1.6 28.Nov.1999 * mmafm: Added `--precision' option for optionally rounding AFM dimensions. Requested by Christopher League . * Many bug fixes for compiling under NeXTSTEP or g++ 2.95. Patches sent in by Melissa O'Neill . * Bug fix: numbers with both decimal point and exponent, like `1.2e5', are parsed correctly. Version 1.5 4.Jul.1999 * mmpfb: Added `--subrs' option for reducing the number of subroutines in the output font. Use this option if you plan to use Acrobat Distiller 3.0 to distill PostScript files including mmpfb-generated fonts. Distiller 3.0 has a low limit on the number of subroutines per font. Several changes to the Type 1 library support this. Problem reported by Thierry Bouche ; tracking help by Tom Kacvinsky . * Both programs accept multiple master instance names, like `MinionMM_367_400_18_', and will interpolate that instance from the multiple master font. * Removed `FONTPATH' and `AFMPATH'. `PSRESOURCEPATH' has been preferred for a couple months. * Updated ErrorHandler. Version 1.4.1 26.Jun.1999 * mmpfb: Also comment out the /UniqueID in the Private dictionary, if any. Reported by Thierry Bouche . Version 1.4 25.Jun.1999 * mmpfb: Always comment out any /UniqueID in the font. This bug prevented some printers from printing files with mmpfb-interpolated fonts. Reported by Thierry Bouche . * mmpfb: Comment out `Blend...' entries in the FontInfo dictionary. Now Adobe Acrobat Distiller can handle mmpfb-interpolated fonts; it correctly treats them like single-master fonts. Problem reported by Thierry Bouche . * mmpfb: Comment out multiple-master-specific dictionary entries, rather than removing them entirely. * mmpfb: Interpolates Blend FontInfo dictionary entries, like `UnderlinePosition' (maybe; can't find any fonts that use them, so it's untested). Version 1.3.1 21.May.1999 * Changed libraries to conform to STL interfaces. * Change to psres.cc to fix compilation bug under old C++ compilers. Version 1.3 11.Apr.1999 * Mmafm will now automatically run `mmpfb --amcp-info' when necessary, so you don't have to create the AMCP files yourself. Caveat: This will only work if you use the PSRESOURCEPATH environment variable and have PSres.upr files set up correctly. * mmafm: Added the PSRESOURCEPATH environment variable, in favor of AFMPATH and FONTPATH. * mmafm: Checks for completely unknown design vectors. * mmpfb: Now uses the PSRESOURCEPATH environment variable to look for fonts by name. * mmpfb: Modifies the output font's XUID to prevent font cache pollution. * Improved documentation. * Unfortunately, this version still doesn't work under NeXTSTEP. Version 1.3b2 22.Jan.1999 * Don't use `index' as a method name; it's a macro under NeXTSTEP. Reported by Melissa O'Neill . * Patch around problems with NeXTSTEP's strtod and strtol. Also reported by Melissa O'Neill . Version 1.3b1 12.Jan.1999 * Han The Thanh reports that Acrobat Reader gives a "bad /BBox" warning on mmpfb-interpolated fonts. This seems to be because mmpfb would produce fractional FontBBox entries. Fix: round the FontBBox entries so it contains integers. * Small bug fix: negative non-integers were formerly read incorrectly, introducing an error of not more than 2 integer units. Version 1.2 18.Dec.1998 * Better error messages and fewer coredumps on bad files. * The mminstance package now uses automake. Version 1.1 27.Sep.1998 * mmpfb: Changes to remove all multiple master commands in the output font, not just most of them. * mmpfb: Added error message on bad input file. * Removed hackery which prevented linking with -lstdc++. * `--help' now prints on stdout, as the GNU standards require. * Makefiles: added `make uninstall' target, enabled `./configure's program name transformations, made VPATH builds possible. Version 1.0 17.Sep.1998 * No changes; just decided it was stable. Version 0.92 2.Sep.1998 * Code reorganization in metrics. (Removed LineScanner, which wasn't a general design; split into a more general Slurper and a specific AfmParser.) Version 0.91 15.May.1998 * mmafm: Nonexistent files caused a coredump instead of an error (fixed). * mmafm: Added support for finding AMFMs via path variables and PSres.upr files (you don't have to give an AMFM filename on the command line, you can give a font name). Version 0.9 4.Mar.1998 * Fixed a bug in parsing fonts with intermediate masters. * mmafm: Added support for finding AFMs via path variables and PSres.upr files, and for giving their filenames on the command line. * Wrote manual pages. Version 0.8 * Major release: Mmafm uses a new AFM/AMFM parsing library. * Restructured the two packages (mmafm and mmpfb) into one package (mminstance) containing both programs. * Improved error messages, command line behavior, usage, and help. Version 0.62 * Fixed small bug in t1interp.cc which caused serious problems. (Function Type1Interp::number() fell off the end instead of returning true.) Bug reported by Melissa O'Neill . Version 0.6 * Major release: Both programs use a new, modular Type 1 parsing library, they take real numbers as arguments, and the configure scripts no longer try to link with -lstdc++. Thanks to Melissa O'Neill for suggestions. * mmafm looks for separate .amcp files for intermediate master conversion programs. Suggested by Melissa O'Neill . * mmpfb can read and generate PFA fonts. * Other fixes. Version 0.5 * Fixed bug preventing the programs from working with Kepler. Version 0.4 * Fixed mmpfb to handle older multiple master fonts (Myriad and Minion) and to generate non-truncated PFBs. Version 0.2 16.Aug.1997 * Fixed serious bug in normalize_vector that resulted in incorrect output. Version 0.1 21.Jul.1997 * Initial release. lcdf-typetools-2.108/t1lint/0000755000175000017500000000000013423377073012721 500000000000000lcdf-typetools-2.108/t1lint/t1lint.10000644000175000017500000000200713423376706014137 00000000000000.ds V 2.108 .de M .BR "\\$1" "(\\$2)\\$3" .. .de Sp .if n .sp .if t .sp 0.4 .. .TH T1LINT 1 "LCDF Typetools" "Version \*V" .SH NAME t1lint \- check a PostScript Type 1 font for correctness .SH SYNOPSIS .B t1lint \%\fIfont\fR [\fIfont\fR...] .SH DESCRIPTION .BR T1lint checks PostScript Type 1 font programs for correctness. Any errors or variances from the specification are reported to standard error. If there are no errors, the command prints nothing. It exits with status 0 if all fonts were OK, and status 1 otherwise. If no input files are supplied, t1lint reads a font from the standard input. ' .SH OPTIONS .PD 0 .TP 5 .BR \-q ", " \-\-quiet Do not generate any error messages. The only output will be the exit status. ' .Sp .TP 5 .BR \-h ", " \-\-help Print usage information and exit. ' .Sp .TP 5 .BR \-v ", " \-\-version Print the version number and some short non-warranty information and exit. .PD ' .SH "SEE ALSO" .LP .M t1disasm 1 .LP .I "Adobe Type 1 Font Format" ' .SH AUTHOR Eddie Kohler (ekohler@gmail.com) lcdf-typetools-2.108/t1lint/cscheck.hh0000664000175000017500000000547612732752520014577 00000000000000#ifndef CSCHECK_HH #define CSCHECK_HH #include #include #include #include #include #include template class CharstringCheckerErrorHandler : public ErrorVeneer { public: CharstringCheckerErrorHandler(ErrorHandler *errh, T *checker) : ErrorVeneer(errh), _checker(checker) { } String decorate(const String &str); private: T *_checker; }; class CharstringChecker : public Efont::CharstringInterp { public: CharstringChecker(); CharstringChecker(const Vector &weight_vec); bool error(int, int); bool callothersubr(); bool type1_command(int); bool check(const Efont::CharstringContext &, ErrorHandler *); int ncommand() const { return _ncommand; } int subrno() const { return _subrno; } private: ErrorHandler *_errh; int _ncommand; int _subrno; Point _cp; bool _started; bool _flex; bool _cp_exists; bool _hstem; bool _hstem3; bool _vstem; bool _vstem3; bool _just_flexed; bool _counter_controlled; int _last_command; Vector _h_hstem; Vector _h_vstem; Vector _h_hstem3; Vector _h_vstem3; void stem(double, double, const char *); void check_stem3(const char *); void moveto(double, double, bool cp_exists = true); void rmoveto(double, double); void rlineto(double, double); void rrcurveto(double, double, double, double, double, double); }; class CharstringSubrChecker : public Efont::CharstringInterp { public: CharstringSubrChecker(); CharstringSubrChecker(const Vector &weight_vec); bool error(int, int); bool type1_command(int); bool check(const Efont::CharstringContext &, ErrorHandler *); int ncommand() const { return -1; } int subrno() const { return -1; } private: ErrorHandler *_errh; bool _returned; }; template String CharstringCheckerErrorHandler::decorate(const String &str) { StringAccum sa; const char *s = skip_anno(str.begin(), str.end()); while (s < str.end() && isspace((unsigned char) *s)) ++s; sa.append(str.begin(), s); if (_checker->subrno() >= 0) sa << "called from "; if (_checker->ncommand() >= 0) sa << "command " << (_checker->ncommand() - 1) << ':'; if (sa) sa << ' '; if (s + 11 < str.end() && memcmp(s, "charstring ", 11) == 0) { bool quote_parity = 0; const char *last = s + 11; for (const char *x = last; x != str.end(); ++x) if (*x == '\'') { sa.append(last, x); sa << format(quote_parity ? "%>" : "%<"); quote_parity = !quote_parity; last = x + 1; } sa.append(last, str.end()); } else sa.append(s, str.end()); return ErrorVeneer::decorate(sa.take_string()); } #endif lcdf-typetools-2.108/t1lint/Makefile.in0000644000175000017500000005203213423376574014715 00000000000000# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : bin_PROGRAMS = t1lint$(EXEEXT) subdir = t1lint ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/lcdf-typetools.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/autoconf.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" PROGRAMS = $(bin_PROGRAMS) am_t1lint_OBJECTS = cscheck.$(OBJEXT) t1lint.$(OBJEXT) t1lint_OBJECTS = $(am_t1lint_OBJECTS) t1lint_DEPENDENCIES = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(t1lint_SOURCES) DIST_SOURCES = $(t1lint_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KPATHSEA_DEPEND = @KPATHSEA_DEPEND@ KPATHSEA_INCLUDES = @KPATHSEA_INCLUDES@ KPATHSEA_LIBS = @KPATHSEA_LIBS@ KPATHSEA_RULE = @KPATHSEA_RULE@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SELECTED_SUBDIRS = @SELECTED_SUBDIRS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TEMPLATE_OBJS = @TEMPLATE_OBJS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ encdir = @encdir@ exec_prefix = @exec_prefix@ glyphlistdir = @glyphlistdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign man_MANS = t1lint.1 t1lint_SOURCES = cscheck.hh cscheck.cc \ t1lint.cc t1lint_LDADD = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_CPPFLAGS = -I$(srcdir)/../include CLEANFILES = @TEMPLATE_OBJS@ EXTRA_DIST = t1lint.1 all: all-am .SUFFIXES: .SUFFIXES: .cc .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign t1lint/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign t1lint/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) t1lint$(EXEEXT): $(t1lint_OBJECTS) $(t1lint_DEPENDENCIES) $(EXTRA_t1lint_DEPENDENCIES) @rm -f t1lint$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(t1lint_OBJECTS) $(t1lint_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cscheck.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1lint.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-man uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-binPROGRAMS install-data install-data-am \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-man1 install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-binPROGRAMS uninstall-man uninstall-man1 .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lcdf-typetools-2.108/t1lint/cscheck.cc0000644000175000017500000003245513423375330014556 00000000000000/* cscheck.{cc,hh} -- checking Type 1 charstrings for validity * * Copyright (c) 1999-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include "cscheck.hh" #include #include #include using namespace Efont; #define CHECK_STACK_GE(numargs) do { if (size() < numargs) return error(errUnderflow, cmd); } while (0) #define CHECK_STACK_EQ(numargs) do { CHECK_STACK_GE(numargs); if (size() > numargs) _errh->warning("too many arguments to %<%s%> (have %d, expected %d)", Charstring::command_name(cmd).c_str(), size(), numargs); } while (0) #define CHECK_STACK_CPEQ(numargs) do { CHECK_STACK_EQ(numargs); if (!_cp_exists) return error(errCurrentPoint, cmd); } while (0) CharstringChecker::CharstringChecker() : CharstringInterp(), _errh(0) { set_careful(true); } CharstringChecker::CharstringChecker(const Vector &weight) : CharstringInterp(weight), _errh(0) { set_careful(true); } void CharstringChecker::stem(double y, double dy, const char *cmd_name) { bool is_v = (cmd_name[0] == 'v'); Vector &hints = (is_v ? _h_vstem : _h_hstem); const char *dimen_name = (is_v ? "x" : "y"); if (dy < 0) { y += dy; dy = -dy; } if (dy < 0.5) _errh->warning("small delta-%s in %<%s%> (%g)", dimen_name, cmd_name, dy); for (int i = 0; i < hints.size(); i += 2) if ((hints[i] >= y && hints[i+1] <= y) || (hints[i] >= y+dy && hints[i+1] <= y+dy)) _errh->warning("overlapping %<%s%> hints", cmd_name); hints.push_back(y); hints.push_back(y+dy); } void CharstringChecker::check_stem3(const char *cmd_name) { bool is_v = (cmd_name[0] == 'v'); Vector &hints = (is_v ? _h_vstem : _h_hstem); Vector &old_hints = (is_v ? _h_vstem3 : _h_hstem3); assert(hints.size() == 6); // sort hints int i0, i1, i2; if (hints[0] > hints[2]) i0 = 2, i1 = 0; else i0 = 0, i1 = 2; if (hints[4] < hints[i0]) i2 = i1, i1 = i0, i0 = 4; else if (hints[4] < hints[i1]) i2 = i1, i1 = 4; else i2 = 4; // check constraints. count "almost equal" as equal double stemw0 = hints[i0+1] - hints[i0]; double stemw2 = hints[i2+1] - hints[i2]; if ((int)(1024*(stemw0 - stemw2) + .5) != 0) _errh->error("bad %<%s%>: extreme stem widths unequal (%g, %g)", cmd_name, stemw0, stemw2); double c0 = (hints[i0] + hints[i0+1])/2; double c1 = (hints[i1] + hints[i1+1])/2; double c2 = (hints[i2] + hints[i2+1])/2; if ((int)(1024*((c1 - c0) - (c2 - c1)) + .5) != 0) _errh->error("bad %<%s%>: stem gaps unequal (%g, %g)", cmd_name, c1-c0, c2-c1); // compare to old hints if (old_hints.size()) { for (int i = 0; i < old_hints.size(); i++) if (hints[i] != old_hints[i]) { _errh->warning("%<%s%> conflicts with old %<%s%>", cmd_name, cmd_name); break; } } old_hints = hints; } void CharstringChecker::moveto(double, double, bool cp_exists) { _cp_exists = cp_exists; } void CharstringChecker::rmoveto(double, double) { _cp_exists = true; _just_flexed = false; } void CharstringChecker::rlineto(double, double) { } void CharstringChecker::rrcurveto(double, double, double, double, double, double) { } bool CharstringChecker::error(int which, int data) { CharstringInterp::error(which, data); _errh->error("%s", error_string().c_str()); return false; } bool CharstringChecker::callothersubr() { int othersubrnum = (int)top(0); int n = (int)top(1); int i; pop(2); if (othersubrnum < 0 || size() < n) return false; if (!_started && (othersubrnum < Cs::othcCountercontrolpart || othersubrnum > Cs::othcMM6)) _errh->warning("first command not % or %"); bool retval = true; switch (othersubrnum) { case Cs::othcFlexend: if (n != 3) { _errh->error("wrong number of arguments to Flex"); goto unknown; } if (!_flex) { _errh->error("no Flex in progress"); retval = false; } else if (ps_size() != 16) { _errh->error("Flex needs 16 arguments, have %d", ps_size()); retval = false; } else { ps_clear(); ps_push(top(0)); ps_push(top(1)); _flex = false; } break; case Cs::othcFlexbegin: if (n != 0) { _errh->error("wrong number of arguments to Flex"); goto unknown; } ps_clear(); ps_push(_cp.x); ps_push(_cp.y); _flex = true; _just_flexed = true; //_flex_connect = _connect; break; case Cs::othcFlexmiddle: if (n != 0) { _errh->error("wrong number of arguments to Flex"); goto unknown; } if (!_flex) retval = error(errFlex, 0); else { if (_just_flexed) _errh->error("Flex control points must be separated by a moveto"); ps_push(_cp.x); ps_push(_cp.y); _just_flexed = true; } break; case Cs::othcReplacehints: if (n != 1) { _errh->error("wrong number of arguments to hint replacement"); goto unknown; } ps_clear(); ps_push(top()); _h_hstem.clear(); _h_vstem.clear(); break; case Cs::othcCountercontrolpart: case Cs::othcCountercontrol: if (_counter_controlled) _errh->error("duplicate counter control instructions"); else if (_started && _last_command != 256 + Cs::othcCountercontrolpart && _last_command != Cs::cSbw && _last_command != Cs::cHsbw) _errh->error("counter control must appear immediately after % or %"); if (n < 0 || n > 22) _errh->error("too many arguments to counter control, max 22"); else if (n != size()) { _errh->error("too few arguments to counter control, expected %d", size()); n = size(); } ps_clear(); _counter_controlled = (othersubrnum == Cs::othcCountercontrol); break; case Cs::othcMM1: case Cs::othcMM2: case Cs::othcMM3: case Cs::othcMM4: case Cs::othcMM6: retval = mm_command(othersubrnum, n); goto skip_pop; default: // unknown unknown: _errh->warning("unknown callothersubr %<%d%>", othersubrnum); ps_clear(); for (i = 0; i < n; i++) ps_push(top(i)); break; } pop(n); if (_last_command == 256 + Cs::othcCountercontrolpart && othersubrnum != Cs::othcCountercontrol) _errh->error("partial counter control instruction"); _last_command = 256 + othersubrnum; skip_pop: return retval; } //#define DEBUG(s) printf s #define DEBUG(s) bool CharstringChecker::type1_command(int cmd) { if (_subrno < 0) ++_ncommand; if (cmd == Cs::cCallsubr) { int old_subrno = _subrno; _subrno = (size() > 1 ? (int) top(0) : -300); bool result = callsubr_command(); _subrno = old_subrno; return result; } else if (cmd == Cs::cCallothersubr) { CHECK_STACK_GE(2); return callothersubr(); } else if (cmd == Cs::cReturn) { return false; } else if (cmd == Cs::cPop || cmd == Cs::cDiv) { return arith_command(cmd); } if (cmd != Cs::cHsbw && cmd != Cs::cSbw) { if (!_started) _errh->warning("first command not % or %"); } else { if (_started) _errh->error("duplicate % or %"); } _started = true; switch (cmd) { case Cs::cHsbw: CHECK_STACK_EQ(2); moveto(at(0), 0, false); clear(); break; case Cs::cSbw: CHECK_STACK_EQ(4); moveto(at(0), at(1), false); clear(); break; case Cs::cClosepath: _cp_exists = false; clear(); break; case Cs::cHlineto: CHECK_STACK_CPEQ(1); rlineto(at(0), 0); clear(); break; case Cs::cHmoveto: CHECK_STACK_EQ(1); rmoveto(at(0), 0); clear(); break; case Cs::cHvcurveto: CHECK_STACK_CPEQ(4); rrcurveto(at(0), 0, at(1), at(2), 0, at(3)); clear(); break; case Cs::cRlineto: CHECK_STACK_CPEQ(2); rlineto(at(0), at(1)); clear(); break; case Cs::cRmoveto: CHECK_STACK_EQ(2); rmoveto(at(0), at(1)); clear(); break; case Cs::cRrcurveto: CHECK_STACK_CPEQ(6); rrcurveto(at(0), at(1), at(2), at(3), at(4), at(5)); clear(); break; case Cs::cVhcurveto: CHECK_STACK_CPEQ(4); rrcurveto(0, at(0), at(1), at(2), at(3), 0); clear(); break; case Cs::cVlineto: CHECK_STACK_CPEQ(1); rlineto(0, at(0)); clear(); break; case Cs::cVmoveto: CHECK_STACK_EQ(1); rmoveto(0, at(0)); clear(); break; case Cs::cHstem: CHECK_STACK_EQ(2); if (_hstem3 && !_hstem) _errh->error("charstring has both % and %"); _hstem = true; stem(at(0), at(1), "hstem"); clear(); break; case Cs::cVstem: CHECK_STACK_EQ(2); if (_vstem3 && !_vstem) _errh->error("charstring has both % and %"); _vstem = true; stem(at(0), at(1), "vstem"); clear(); break; case Cs::cEndchar: set_done(); _last_command = cmd; return false; case Cs::cDotsection: break; case Cs::cVstem3: CHECK_STACK_EQ(6); if (_vstem && !_vstem3) _errh->error("charstring has both % and %"); _vstem3 = true; _h_vstem.clear(); stem(at(0), at(1), "vstem3"); stem(at(2), at(3), "vstem3"); stem(at(4), at(5), "vstem3"); check_stem3("vstem3"); clear(); break; case Cs::cHstem3: CHECK_STACK_EQ(6); if (_hstem && !_hstem3) _errh->error("charstring has both % and %"); _hstem3 = true; _h_hstem.clear(); stem(at(0), at(1), "hstem3"); stem(at(2), at(3), "hstem3"); stem(at(4), at(5), "hstem3"); check_stem3("hstem3"); clear(); break; case Cs::cSeac: { CHECK_STACK_EQ(5); #if 0 double asb = at(0); double adx = at(1); double ady = at(2); int bchar = (int)at(3); int achar = (int)at(4); double ax = adx - asb + _sidebearing.x; double ay = ady + _sidebearing.y; Point real_sidebearing = _sidebearing; Point real_char_width = _char_width; Point original_origin = _origin; Type1Encoding *adobe = Type1Encoding::standard_encoding(); if (!adobe) return error(errInternal, cmd); Type1Charstring *t1cs = get_glyph((*adobe)[achar]); if (!t1cs) ERROR(errGlyph); _origin = Point(ax, ay); init(); t1cs->run(*this); _origin = original_origin; if (error()) return false; t1cs = get_glyph((*adobe)[bchar]); if (!t1cs) ERROR(errGlyph); init(); t1cs->run(*this); _sidebearing = real_sidebearing; _char_width = real_char_width; #endif return false; } case Cs::cSetcurrentpoint: CHECK_STACK_EQ(2); _cp = Point(at(0), at(1)); _cp_exists = true; clear(); break; case Cs::cPut: case Cs::cGet: case Cs::cStore: case Cs::cLoad: return vector_command(cmd); default: return arith_command(cmd); } if (_last_command == 256 + Cs::othcCountercontrolpart) _errh->error("partial counter control instruction"); _last_command = cmd; return true; } bool CharstringChecker::check(const CharstringContext &g, ErrorHandler *errh) { CharstringCheckerErrorHandler merrh(errh, this); _errh = &merrh; int old_errors = errh->nerrors(); _started = false; _flex = false; _hstem = _hstem3 = _vstem = _vstem3 = false; _just_flexed = _counter_controlled = false; _last_command = -1; _h_hstem.clear(); _h_vstem.clear(); _h_hstem3.clear(); _h_vstem3.clear(); _ncommand = 0; _subrno = -1; CharstringInterp::interpret(g); return errh->nerrors() == old_errors; } CharstringSubrChecker::CharstringSubrChecker() : CharstringInterp(), _errh(0) { set_careful(true); } CharstringSubrChecker::CharstringSubrChecker(const Vector &weight) : CharstringInterp(weight), _errh(0) { set_careful(true); } bool CharstringSubrChecker::error(int error, int data) { CharstringInterp::error(error, data); _errh->error("%s", error_string().c_str()); return false; } bool CharstringSubrChecker::type1_command(int cmd) { switch (cmd) { case Cs::cReturn: _returned = true; return false; default: clear(); return true; } } bool CharstringSubrChecker::check(const CharstringContext &g, ErrorHandler *errh) { CharstringCheckerErrorHandler merrh(errh, this); _errh = &merrh; int old_errors = errh->nerrors(); _returned = false; CharstringInterp::interpret(g); if (!_returned) _errh->error("subroutine does not return"); return errh->nerrors() == old_errors; } lcdf-typetools-2.108/t1lint/t1lint.cc0000644000175000017500000003166413423375330014367 00000000000000/* t1lint.cc -- driver for checking Type 1 fonts for validity * * Copyright (c) 1999-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include "cscheck.hh" #include #include #include #include #include #include #include #include #ifdef HAVE_CTIME # include #endif #if defined(_MSDOS) || defined(_WIN32) # include # include #endif using namespace Efont; #define VERSION_OPT 301 #define HELP_OPT 302 #define QUIET_OPT 303 const Clp_Option options[] = { { "help", 'h', HELP_OPT, 0, 0 }, { "quiet", 'q', QUIET_OPT, 0, Clp_Negate }, { "version", 0, VERSION_OPT, 0, 0 }, }; static const char *program_name; void usage_error(ErrorHandler *errh, const char *error_message, ...) { va_list val; va_start(val, error_message); if (!error_message) errh->message("Usage: %s [OPTION]... FONT", program_name); else errh->xmessage(ErrorHandler::e_error, error_message, val); errh->message("Type %s --help for more information.", program_name); exit(1); } void usage() { FileErrorHandler uerrh(stdout); uerrh.message("\ % checks a PostScript Type 1 font for correctness. Any errors or\n\ divergences from the specification are reported to standard error. Nothing is\n\ printed for correct fonts. The command exits with status 0 if there are no\n\ errors, and status 1 otherwise.\n\ \n\ Usage: %s [OPTION]... FONT [...]\n\ \n\ Each FONT is the name of a PFA or PFB font file.\n\ \n\ Options:\n\ -h, --help Print this message and exit.\n\ -q, --quiet Do not report errors to standard error.\n\ --version Print version number and exit.\n\ \n\ Report bugs to .\n", program_name); } /***** * CHECKS **/ static bool get_num_array(Type1Font *font, int dictionary, const char *name, Vector &v, ErrorHandler *errh, bool mandatory = false) { if (Type1Definition *d = font->dict(dictionary, name)) { if (d->value_numvec(v)) return true; errh->error("%s not an array of numbers", name); v.clear(); } else if (mandatory) errh->error("%s not defined", name); return false; } static bool get_integer(Type1Font *font, int dictionary, const char *name, int &v, ErrorHandler *errh, bool mandatory = false) { Type1Definition *d = font->dict(dictionary, name); double scratch; if (d && d->value_int(v)) return true; else if (d && d->value_num(scratch)) { errh->warning("%s not an integer", name); v = (int)scratch; return true; } else if (d) errh->error("%s not a number", name); else if (mandatory) errh->error("%s not defined", name); return false; } // BLUES static void check_blue_array(Vector &blues, const char *name, double BlueScale, ErrorHandler *errh) { if (blues.size() % 2 != 0) { errh->error("%s has an odd number of entries", name); blues.push_back(blues.back()); } for (int i = 0; i < blues.size(); i++) if (blues[i] != (double)((int)blues[i])) { errh->warning("some %s entries are not integers", name); break; } double max_diff = 1 / BlueScale; for (int i = 0; i < blues.size(); i += 2) { if (blues[i] > blues[i+1]) errh->error("%s zone %d in the wrong order", name, i/2); else if (blues[i+1] - blues[i] >= max_diff) errh->error("%s zone %d too large in relation to BlueScale (size %g, max %g [%g])", name, i/2, blues[i+1] - blues[i], max_diff, BlueScale); } } static void check_blue_overlap(Vector &bl1, const char *name1, Vector &bl2, const char *name2, int BlueFuzz, ErrorHandler *errh) { int min_fuzz = 2*BlueFuzz + 1; for (int i = 2; i < bl1.size(); i += 2) { int thresh = (&bl1 == &bl2 ? i : bl2.size()); for (int j = 0; j < thresh; j += 2) { if ((bl2[j] >= bl1[i] && bl2[j] <= bl1[i+1]) || (bl2[j+1] >= bl1[i] && bl2[j+1] <= bl1[i+1])) errh->error("%s zone %d and %s zone %d overlap", name1, i/2, name2, j/2); else if ((bl2[j] >= bl1[i+1] && bl2[j] < bl1[i+1]+min_fuzz) || (bl2[j+1] <= bl1[i] && bl2[j+1]+min_fuzz > bl1[i])) errh->error("%s zone %d and %s zone %d overlap within BlueFuzz", name1, i/2, name2, j/2); } } } static void check_blues(Type1Font *font, ErrorHandler *errh) { Type1Definition *d; // BlueScale double BlueScale; bool ok = false; if ((d = font->p_dict("BlueScale"))) { if (!d->value_num(BlueScale)) errh->error("BlueScale not a real number"); else if (BlueScale <= 0) errh->error("BlueScale less than or equal to 0"); else { if (BlueScale > 0.5) errh->error("suspiciously large BlueScale (%g)", BlueScale); ok = true; } } if (!ok) BlueScale = 0.039625; // BlueShift int BlueShift = -1; if (get_integer(font, Type1Font::dP, "BlueShift", BlueShift, errh) && BlueShift < 0) errh->error("BlueShift less than 0"); if (BlueShift < 0) BlueShift = 7; // BlueFuzz int BlueFuzz = -1; if (get_integer(font, Type1Font::dP, "BlueFuzz", BlueFuzz, errh) && BlueFuzz < 0) errh->error("BlueFuzz less than 0"); if (BlueFuzz < 0) BlueFuzz = 1; else if (BlueFuzz > 10) errh->warning("suspiciously large BlueFuzz (%d)", BlueFuzz); // BlueValues Vector BlueValues, OtherBlues; get_num_array(font, Type1Font::dP, "BlueValues", BlueValues, errh, true); get_num_array(font, Type1Font::dP, "OtherBlues", OtherBlues, errh); check_blue_array(BlueValues, "BlueValues", BlueScale, errh); if (BlueValues.size() > 14) errh->error("too many zones in BlueValues (max 7)"); check_blue_array(OtherBlues, "OtherBlues", BlueScale, errh); if (OtherBlues.size() > 10) errh->error("too many zones in OtherBlues (max 5)"); check_blue_overlap(BlueValues, "BlueValues", BlueValues, "BlueValues", BlueFuzz, errh); check_blue_overlap(OtherBlues, "OtherBlues", OtherBlues, "OtherBlues", BlueFuzz, errh); check_blue_overlap(BlueValues, "BlueValues", OtherBlues, "OtherBlues", BlueFuzz, errh); // FamilyBlues Vector FamilyBlues, FamilyOtherBlues; get_num_array(font, Type1Font::dP, "FamilyBlues", FamilyBlues, errh); get_num_array(font, Type1Font::dP, "FamilyOtherBlues", FamilyOtherBlues, errh); check_blue_array(FamilyBlues, "FamilyBlues", BlueScale, errh); if (FamilyBlues.size() > 14) errh->error("too many zones in FamilyBlues (max 7)"); check_blue_array(FamilyOtherBlues, "FamilyOtherBlues", BlueScale, errh); if (FamilyOtherBlues.size() > 10) errh->error("too many zones in FamilyOtherBlues (max 5)"); check_blue_overlap(FamilyBlues, "FamilyBlues", FamilyBlues, "FamilyBlues", BlueFuzz, errh); check_blue_overlap(FamilyOtherBlues, "FamilyOtherBlues", FamilyOtherBlues, "FamilyOtherBlues", BlueFuzz, errh); check_blue_overlap(FamilyBlues, "FamilyBlues", FamilyOtherBlues, "FamilyOtherBlues", BlueFuzz, errh); } // STEMS void check_stem_snap(Vector &stem_snap, double main, bool is_v, ErrorHandler *errh) { const char *name = (is_v ? "V" : "H"); if (stem_snap.size() > 12) errh->error("StemSnap%s has more than 12 entries", name); for (int i = 0; i < stem_snap.size() - 1; i++) if (stem_snap[i] >= stem_snap[i+1]) { errh->error("StemSnap%s is not sorted in increasing order", name); break; } for (int i = 0; i < stem_snap.size(); i++) if (stem_snap[i] == main) return; if (main >= 0) errh->warning("Std%sW not in StemSnap%s array", name, name); } void check_stems(Type1Font *font, ErrorHandler *errh) { Vector StdHW, StdVW, StemSnapH, StemSnapV; if (get_num_array(font, Type1Font::dP, "StdHW", StdHW, errh)) { if (StdHW.size() != 1) errh->error("StdHW has %d entries (exactly one required)", StdHW.size()); if (StdHW.size() > 0 && StdHW[0] <= 0) errh->error("StdHW entry less than or equal to 0"); } if (get_num_array(font, Type1Font::dP, "StdVW", StdVW, errh)) { if (StdVW.size() != 1) errh->error("StdVW has %d entries (exactly one required)", StdVW.size()); if (StdVW.size() > 0 && StdVW[0] <= 0) errh->error("StdVW entry less than or equal to 0"); } if (get_num_array(font, Type1Font::dP, "StemSnapH", StemSnapH, errh)) check_stem_snap(StemSnapH, StdHW.size() ? StdHW[0] : -1000, false, errh); if (get_num_array(font, Type1Font::dP, "StemSnapV", StemSnapV, errh)) check_stem_snap(StemSnapV, StdVW.size() ? StdVW[0] : -1000, true, errh); } // MAIN static void do_file(const char *filename, PsresDatabase *psres, ErrorHandler *errh, ErrorHandler *err_errh) { FILE *f; if (strcmp(filename, "-") == 0) { f = stdin; filename = ""; #if defined(_MSDOS) || defined(_WIN32) _setmode(_fileno(f), _O_BINARY); #endif } else f = fopen(filename, "rb"); if (!f) { // check for PostScript name Filename fn = psres->filename_value("FontOutline", filename); f = fn.open_read(); } if (!f) err_errh->fatal("%s: %s", filename, strerror(errno)); Type1Reader *reader; int c = getc(f); ungetc(c, f); if (c == EOF) err_errh->fatal("%s: empty file", filename); if (c == 128) reader = new Type1PFBReader(f); else reader = new Type1PFAReader(f); Type1Font *font = new Type1Font(*reader); if (font) { LandmarkErrorHandler cerrh(errh, filename); // check UniqueID values int UniqueID = -1, UniqueID2 = -1; if (get_integer(font, Type1Font::dF, "UniqueID", UniqueID, errh) && (UniqueID < 0 || UniqueID > 0xFFFFFF)) cerrh.error("UniqueID not in the range 0-16777215"); if (get_integer(font, Type1Font::dP, "UniqueID", UniqueID2, errh) && (UniqueID2 < 0 || UniqueID2 > 0xFFFFFF)) cerrh.error("Private UniqueID not in the range 0-16777215"); if (UniqueID >= 0 && UniqueID2 >= 0 && UniqueID != UniqueID2) cerrh.error("Private UniqueID does not equal font UniqueID"); // check XUID values Vector XUID; if (get_num_array(font, Type1Font::dF, "XUID", XUID, errh)) { if (XUID.size() == 0) cerrh.error("empty XUID"); for (int i = 0; i < XUID.size(); i++) { if (floor(XUID[i]) != XUID[i] || XUID[i] < 0 || XUID[i] > 0xFFFFFF) { cerrh.error("element of XUID not an integer in the range 0-16777215"); break; } } } check_blues(font, &cerrh); check_stems(font, &cerrh); MultipleMasterSpace *mmspace = font->create_mmspace(&cerrh); Vector weight_vector; if (mmspace) weight_vector = mmspace->default_weight_vector(); int gc = font->nglyphs(); CharstringChecker cc(weight_vector); for (int i = 0; i < gc; i++) { ContextErrorHandler derrh (&cerrh, "While interpreting %<%s%>:", font->glyph_name(i).c_str()); cc.check(font->glyph_context(i), &derrh); } int ns = font->nsubrs(); CharstringSubrChecker csc(weight_vector); for (int i = 0; i < ns; ++i) if (Type1Charstring *cs = font->subr(i)) { ContextErrorHandler derrh(&cerrh, "While interpreting subr %d:", i); CharstringContext cctx(font, cs); csc.check(cctx, &derrh); } } delete font; delete reader; } int main(int argc, char *argv[]) { PsresDatabase *psres = new PsresDatabase; psres->add_psres_path(getenv("PSRESOURCEPATH"), 0, false); Clp_Parser *clp = Clp_NewParser(argc, (const char * const *)argv, sizeof(options) / sizeof(options[0]), options); program_name = Clp_ProgramName(clp); ErrorHandler *err_errh = ErrorHandler::static_initialize(new FileErrorHandler(stderr)); ErrorHandler *out_errh = new FileErrorHandler(stdout); ErrorHandler *errh = out_errh; int nfiles = 0; while (1) { int opt = Clp_Next(clp); switch (opt) { case QUIET_OPT: if (clp->negated) errh = out_errh; else errh = new SilentErrorHandler; break; case VERSION_OPT: printf("t1lint (LCDF typetools) %s\n", VERSION); printf("Copyright (C) 1999-2019 Eddie Kohler\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); exit(0); break; case HELP_OPT: usage(); exit(0); break; case Clp_NotOption: do_file(clp->vstr, psres, errh, err_errh); nfiles++; break; case Clp_Done: goto done; case Clp_BadOption: usage_error(err_errh, 0); break; default: break; } } done: if (nfiles == 0) do_file("-", psres, errh, err_errh); return (errh->nerrors() == 0 ? 0 : 1); } lcdf-typetools-2.108/t1lint/Makefile.am0000664000175000017500000000051312732752520014672 00000000000000## Process this file with automake to produce Makefile.in AUTOMAKE_OPTIONS = foreign bin_PROGRAMS = t1lint man_MANS = t1lint.1 t1lint_SOURCES = cscheck.hh cscheck.cc \ t1lint.cc t1lint_LDADD = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_CPPFLAGS = -I$(srcdir)/../include CLEANFILES = @TEMPLATE_OBJS@ EXTRA_DIST = t1lint.1 lcdf-typetools-2.108/t1dotlessj/0000755000175000017500000000000013423377073013602 500000000000000lcdf-typetools-2.108/t1dotlessj/t1dotlessj.cc0000644000175000017500000003003213423375330016115 00000000000000/* t1dotlessj.cc -- driver for creating dotlessj characters from Type 1 fonts * * Copyright (c) 2003-2019 Eddie Kohler * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_CTIME # include #endif #if defined(_MSDOS) || defined(_WIN32) # include # include #endif // also see otftotfm/automatic.cc enum { EXIT_NORMAL = 0, EXIT_DOTLESSJ_EXISTS = 1, EXIT_J_NODOT = 2, EXIT_NO_J = 3, EXIT_ERROR = 4 }; using namespace Efont; #define VERSION_OPT 301 #define HELP_OPT 302 #define QUIET_OPT 303 #define PFA_OPT 304 #define PFB_OPT 305 #define OUTPUT_OPT 306 #define NAME_OPT 307 const Clp_Option options[] = { { "help", 'h', HELP_OPT, 0, 0 }, { "name", 'n', NAME_OPT, Clp_ValString, 0 }, { "output", 'o', OUTPUT_OPT, Clp_ValString, 0 }, { "pfa", 'a', PFA_OPT, 0, 0 }, { "pfb", 'b', PFB_OPT, 0, 0 }, { "quiet", 'q', QUIET_OPT, 0, Clp_Negate }, { "version", 0, VERSION_OPT, 0, 0 }, }; static const char *program_name; void usage_error(ErrorHandler *errh, const char *error_message, ...) { va_list val; va_start(val, error_message); if (!error_message) errh->message("Usage: %s [OPTIONS] [FONTFILE [OUTPUTFILE]]", program_name); else errh->xmessage(ErrorHandler::e_error, error_message, val); errh->message("Type %s --help for more information.", program_name); exit(EXIT_ERROR); } void usage() { FileErrorHandler uerrh(stdout); uerrh.message("\ % reads a PostScript Type 1 font, derives a new PostScript Type 1\n\ font containing just a dotlessj character (by chopping the dot from the j),\n\ and writes it to the standard output.\n\ \n\ Usage: %s [OPTIONS] [FONTFILE [OUTPUTFILE]]\n\ \n\ Options:\n\ -a, --pfa Output PFA font.\n\ -b, --pfb Output PFB font. This is the default.\n\ -o, --output=FILE Write output to FILE instead of standard output.\n\ -n, --name=NAME Set output font%,s PostScript name.\n\ -h, --help Print this message and exit.\n\ -q, --quiet Do not report errors to standard error.\n\ --version Print version number and exit.\n\ \n\ Report bugs to .\n", program_name); } // Sectioner class Sectioner : public Type1CharstringGenInterp { public: Sectioner(int precision); void act_line(int, const Point &, const Point &); void act_curve(int, const Point &, const Point &, const Point &, const Point &); void act_closepath(int); void act_flex(int, const Point &, const Point &, const Point &, const Point &, const Point &, const Point &, const Point &, double); void run(const CharstringContext &g); void undot(PermString, ErrorHandler *); Type1Charstring gen(Type1Font *); private: CharstringBounds _boundser; Vector _sections; Vector _bounds; void append_bounds(); }; Sectioner::Sectioner(int precision) : Type1CharstringGenInterp(precision) { set_direct_hint_replacement(true); } void Sectioner::act_line(int cmd, const Point &p0, const Point &p1) { Type1CharstringGenInterp::act_line(cmd, p0, p1); _boundser.act_line(cmd, p0, p1); } void Sectioner::act_curve(int cmd, const Point &p0, const Point &p1, const Point &p2, const Point &p3) { Type1CharstringGenInterp::act_curve(cmd, p0, p1, p2, p3); _boundser.act_curve(cmd, p0, p1, p2, p3); } void Sectioner::act_flex(int cmd, const Point &p0, const Point &p1, const Point &p2, const Point &p3_4, const Point &p5, const Point &p6, const Point &p7, double flex_depth) { Type1CharstringGenInterp::act_flex(cmd, p0, p1, p2, p3_4, p5, p6, p7, flex_depth); _boundser.act_flex(cmd, p0, p1, p2, p3_4, p5, p6, p7, flex_depth); } void Sectioner::append_bounds() { double bb[5]; _boundser.output(bb, bb[4]); _bounds.push_back((int) floor(bb[0])); _bounds.push_back((int) floor(bb[1])); _bounds.push_back((int) ceil(bb[2])); _bounds.push_back((int) ceil(bb[3])); } void Sectioner::act_closepath(int cmd) { Type1CharstringGenInterp::act_closepath(cmd); Type1Charstring result; Type1CharstringGenInterp::intermediate_output(result); _sections.push_back(result.data_string()); append_bounds(); _boundser.clear(); } void Sectioner::run(const CharstringContext &g) { _boundser.clear(); Type1Charstring last_section; Type1CharstringGenInterp::run(g, last_section); _sections.push_back(last_section.data_string()); append_bounds(); } void Sectioner::undot(PermString font_name, ErrorHandler *errh) { //for (String *s = _sections.begin(); s < _sections.end(); s++) // fprintf(stderr, "%d %s\n", s - _sections.begin(), CharstringUnparser::unparse(Type1Charstring(*s)).c_str()); if (_sections.size() < 3) errh->fatal("<%d>%s: % is already dotless", -EXIT_J_NODOT, font_name.c_str()); int topmost = -1; for (int i = 0; i < _sections.size() - 1; i++) if (topmost < 0 || _bounds[i*4 + 1] > _bounds[topmost*4 + 1]) topmost = i; // check if any sections are below this for (int i = 0; i < _sections.size() - 1; i++) if (_bounds[i*4 + 1] < _bounds[topmost*4 + 1]) goto found_below; errh->fatal("<%d>%s: % is already dotless", -EXIT_J_NODOT, font_name.c_str()); found_below: _sections[topmost] = String(); } Type1Charstring Sectioner::gen(Type1Font *font) { StringAccum sa; for (String *s = _sections.begin(); s < _sections.end(); s++) sa << *s; Type1Charstring in(sa.take_string()), out; Type1CharstringGenInterp gen(precision()); gen.set_hint_replacement_storage(font); gen.run(CharstringContext(program(), &in), out); return out; } // MAIN static Type1Font * do_file(const char *filename, PsresDatabase *psres, ErrorHandler *errh) { FILE *f; if (!filename || strcmp(filename, "-") == 0) { f = stdin; filename = ""; #if defined(_MSDOS) || defined(_WIN32) _setmode(_fileno(f), _O_BINARY); #endif } else f = fopen(filename, "rb"); if (!f) { // check for PostScript name Filename fn = psres->filename_value("FontOutline", filename); f = fn.open_read(); } if (!f) errh->fatal("<%d>%s: %s", -EXIT_ERROR, filename, strerror(errno)); Type1Reader *reader; int c = getc(f); ungetc(c, f); if (c == EOF) errh->fatal("<%d>%s: empty file", -EXIT_ERROR, filename); if (c == 128) reader = new Type1PFBReader(f); else reader = new Type1PFAReader(f); Type1Font *font = new Type1Font(*reader); if (!font->ok()) errh->fatal("<%d>%s: no glyphs in font", -EXIT_ERROR, filename); delete reader; return font; } int main(int argc, char *argv[]) { PsresDatabase *psres = new PsresDatabase; psres->add_psres_path(getenv("PSRESOURCEPATH"), 0, false); Clp_Parser *clp = Clp_NewParser(argc, (const char * const *)argv, sizeof(options) / sizeof(options[0]), options); program_name = Clp_ProgramName(clp); ErrorHandler *errh = ErrorHandler::static_initialize(new FileErrorHandler(stderr)); const char *input_file = 0; FILE *outputf = 0; const char *private_use_dotlessj = "uniF6BE"; bool binary = true; const char *font_name = 0; while (1) { int opt = Clp_Next(clp); switch (opt) { case QUIET_OPT: if (clp->negated) errh = ErrorHandler::default_handler(); else errh = new SilentErrorHandler; break; case NAME_OPT: font_name = clp->vstr; break; case PFA_OPT: binary = false; break; case PFB_OPT: binary = true; break; case OUTPUT_OPT: output_file: if (outputf) usage_error(errh, "output file specified twice"); if (strcmp(clp->vstr, "-") == 0) outputf = stdout; else if (!(outputf = fopen(clp->vstr, "wb"))) errh->fatal("<%d>%s: %s", -EXIT_ERROR, clp->vstr, strerror(errno)); break; case VERSION_OPT: printf("t1dotlessj (LCDF typetools) %s\n", VERSION); printf("Copyright (C) 2003-2019 Eddie Kohler\n\ This is free software; see the source for copying conditions.\n\ There is NO warranty, not even for merchantability or fitness for a\n\ particular purpose.\n"); exit(0); break; case HELP_OPT: usage(); exit(0); break; case Clp_NotOption: if (input_file && outputf) usage_error(errh, "too many arguments"); else if (input_file) goto output_file; else input_file = clp->vstr; break; case Clp_Done: goto done; case Clp_BadOption: usage_error(errh, 0); break; default: break; } } done: Type1Font *font = do_file(input_file, psres, errh); if (!input_file || strcmp(input_file, "-") == 0) input_file = ""; // check for existing dotlessj if (font->glyph("dotlessj")) errh->fatal("<%d>%s: already has a % glyph", -EXIT_DOTLESSJ_EXISTS, font->font_name().c_str()); else if (font->glyph("uni0237")) errh->fatal("<%d>%s: already has a dotlessj glyph at %", -EXIT_DOTLESSJ_EXISTS, font->font_name().c_str()); else if (font->glyph("u0237")) errh->fatal("<%d>%s: already has a dotlessj glyph at %", -EXIT_DOTLESSJ_EXISTS, font->font_name().c_str()); else if (private_use_dotlessj && font->glyph(private_use_dotlessj)) errh->fatal("<%d>%s: already has a dotlessj glyph at %<%s%>", -EXIT_DOTLESSJ_EXISTS, font->font_name().c_str(), private_use_dotlessj); // check for j Type1Charstring *j_cs = font->glyph("j"); if (!j_cs) j_cs = font->glyph("uni006A"); if (!j_cs) j_cs = font->glyph("u006A"); if (!j_cs) errh->fatal("<%d>%s: has no % glyph to make dotless", -EXIT_NO_J, font->font_name().c_str()); // make new font String actual_font_name = (font_name ? String(font_name) : font->font_name() + String("LCDFJ")); if (actual_font_name.length() > 29 && !font_name) { errh->warning("derived font name %<%s%> longer than 29 characters", actual_font_name.c_str()); errh->message("(Use the %<--name%> option to supply your own name.)"); } Vector xuid_extension; xuid_extension.push_back(0x00237237); Type1Font *dotless_font = Type1Font::skeleton_make_copy(font, actual_font_name, &xuid_extension); dotless_font->skeleton_common_subrs(); // copy space and .notdef if (Type1Charstring *notdef = font->glyph(".notdef")) dotless_font->add_glyph(Type1Subr::make_glyph(".notdef", *notdef, " |-")); if (Type1Charstring *space = font->glyph("space")) { dotless_font->add_glyph(Type1Subr::make_glyph("space", *space, " |-")); dotless_font->type1_encoding()->put(' ', "space"); } // create dotless j Sectioner sec(5); sec.run(CharstringContext(font, j_cs)); sec.undot(font->font_name(), errh); Type1Subr *dotlessj = Type1Subr::make_glyph("uni0237", sec.gen(dotless_font), " |-"); dotless_font->add_glyph(dotlessj); //fprintf(stderr, "! %s\n", CharstringUnparser::unparse(dotlessj->t1cs()).c_str()); // encode dotless j dotless_font->type1_encoding()->clear(); dotless_font->type1_encoding()->put('j', "uni0237"); // write it to output if (!outputf) outputf = stdout; if (binary) { #if defined(_MSDOS) || defined(_WIN32) _setmode(_fileno(outputf), _O_BINARY); #endif Type1PFBWriter w(outputf); dotless_font->write(w); } else { Type1PFAWriter w(outputf); dotless_font->write(w); } return (errh->nerrors() == 0 ? EXIT_NORMAL : EXIT_ERROR); } lcdf-typetools-2.108/t1dotlessj/t1dotlessj.10000644000175000017500000000362213423376706015705 00000000000000.ds V 2.108 .de M .BR "\\$1" "(\\$2)\\$3" .. .de Sp .if n .sp .if t .sp 0.4 .. .TH T1DOTLESSJ 1 "LCDF Typetools" "Version \*V" .SH NAME t1dotlessj \- create a dotless-j PostScript Type 1 font .SH SYNOPSIS .B t1dotlessj \%[OPTIONS...] .I font .RI [ outputfile ] .SH DESCRIPTION .BR T1dotlessj creates a PostScript Type\~1 font whose only character is a dotless 'j' matching the input font's design. It works simply by removing the dot from the input font's 'j'. The output font has three characters: '.notdef', \&'space', and 'uni0237', where 'uni0237' is the dotless 'j'. The command fails if the input font already has a dotless 'j' character, or if there seems to be no dot to remove. T1dotlessj writes the created PFA or PFB font to the standard output (but see the .B \-\-output option); if no input file is supplied, it reads a PFA or PFB font from the standard input. ' .SH OPTIONS .PD 0 .TP 5 .BR \-\-output "=\fIfile\fR, " \-o " \fIfile" Send output to .I file instead of standard output. ' .Sp .TP 5 .BR \-\-pfb ", " \-b Output a PFB font. This is the default. ' .Sp .TP 5 .BR \-\-pfa ", " \-a Output a PFA font. ' .Sp .TP 5 .BR \-\-name "=\fIname\fR, " \-n " \fIname" Set the output font's PostScript name to .IR name . The default is .IR InputFontName "LCDFJ." ' .Sp .TP 5 .BR \-q ", " \-\-quiet Do not generate any error messages. ' .Sp .TP 5 .BR \-h ", " \-\-help Print usage information and exit. ' .Sp .TP 5 .BR \-v ", " \-\-version Print the version number and some short non-warranty information and exit. .PD ' .SH "RETURN VALUES" .B T1dotlessj exits with one of the following values: .TP 5 0 A dotless-j font was successfully generated. .TP 5 1 The font already contained a dotless-j character. .TP 5 2 The font's "j" character had no dot to remove. .TP 5 3 The font had no "j" character. .TP 5 >3 An error occurred. ' .SH "SEE ALSO" .LP .I "Adobe Type 1 Font Format" ' .SH AUTHOR Eddie Kohler (ekohler@gmail.com) lcdf-typetools-2.108/t1dotlessj/Makefile.in0000644000175000017500000005112013423376574015573 00000000000000# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : bin_PROGRAMS = t1dotlessj$(EXEEXT) subdir = t1dotlessj ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/lcdf-typetools.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/autoconf.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" PROGRAMS = $(bin_PROGRAMS) am_t1dotlessj_OBJECTS = t1dotlessj.$(OBJEXT) t1dotlessj_OBJECTS = $(am_t1dotlessj_OBJECTS) t1dotlessj_DEPENDENCIES = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(t1dotlessj_SOURCES) DIST_SOURCES = $(t1dotlessj_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KPATHSEA_DEPEND = @KPATHSEA_DEPEND@ KPATHSEA_INCLUDES = @KPATHSEA_INCLUDES@ KPATHSEA_LIBS = @KPATHSEA_LIBS@ KPATHSEA_RULE = @KPATHSEA_RULE@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SELECTED_SUBDIRS = @SELECTED_SUBDIRS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TEMPLATE_OBJS = @TEMPLATE_OBJS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ encdir = @encdir@ exec_prefix = @exec_prefix@ glyphlistdir = @glyphlistdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign man_MANS = t1dotlessj.1 t1dotlessj_SOURCES = t1dotlessj.cc t1dotlessj_LDADD = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_CPPFLAGS = -I$(srcdir)/../include CLEANFILES = @TEMPLATE_OBJS@ EXTRA_DIST = t1dotlessj.1 all: all-am .SUFFIXES: .SUFFIXES: .cc .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign t1dotlessj/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign t1dotlessj/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) t1dotlessj$(EXEEXT): $(t1dotlessj_OBJECTS) $(t1dotlessj_DEPENDENCIES) $(EXTRA_t1dotlessj_DEPENDENCIES) @rm -f t1dotlessj$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(t1dotlessj_OBJECTS) $(t1dotlessj_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1dotlessj.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-man uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-binPROGRAMS install-data install-data-am \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-man1 install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-binPROGRAMS uninstall-man uninstall-man1 .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lcdf-typetools-2.108/t1dotlessj/Makefile.am0000664000175000017500000000051212732752520015552 00000000000000## Process this file with automake to produce Makefile.in AUTOMAKE_OPTIONS = foreign bin_PROGRAMS = t1dotlessj man_MANS = t1dotlessj.1 t1dotlessj_SOURCES = t1dotlessj.cc t1dotlessj_LDADD = ../libefont/libefont.a ../liblcdf/liblcdf.a AM_CPPFLAGS = -I$(srcdir)/../include CLEANFILES = @TEMPLATE_OBJS@ EXTRA_DIST = t1dotlessj.1