diff options
author | Luigi Scarso <luigi.scarso@gmail.com> | 2018-09-05 21:57:30 +0000 |
---|---|---|
committer | Luigi Scarso <luigi.scarso@gmail.com> | 2018-09-05 21:57:30 +0000 |
commit | ecd1605a23ef54d2a4a69e1a361172d350e03b3b (patch) | |
tree | 8ea1d9745c24dbc5e755f13d801fa01e88944650 /Build/source/texk/web2c/luatexdir/font | |
parent | 04563248956e7059aad4fc4f6bf7da18562f7b8c (diff) |
luatex: correct automake file for pplib; replaced cweb files with c files.
git-svn-id: svn://tug.org/texlive/trunk@48594 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/font')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/dofont.c (renamed from Build/source/texk/web2c/luatexdir/font/dofont.w) | 82 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/luafont.c (renamed from Build/source/texk/web2c/luatexdir/font/luafont.w) | 730 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/mapfile.c | 770 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/mapfile.w | 715 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/pkin.c (renamed from Build/source/texk/web2c/luatexdir/font/pkin.w) | 288 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/sfnt.c (renamed from Build/source/texk/web2c/luatexdir/font/sfnt.w) | 198 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/subfont.c (renamed from Build/source/texk/web2c/luatexdir/font/subfont.w) | 112 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/texfont.c (renamed from Build/source/texk/web2c/luatexdir/font/texfont.w) | 406 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/tfmofm.c | 1186 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/tfmofm.w | 1119 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/tounicode.c (renamed from Build/source/texk/web2c/luatexdir/font/tounicode.w) | 372 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/tt_glyf.c (renamed from Build/source/texk/web2c/luatexdir/font/tt_glyf.w) | 316 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/tt_table.c (renamed from Build/source/texk/web2c/luatexdir/font/tt_table.w) | 152 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/vfovf.c | 1444 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/vfovf.w | 1480 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/vfpacket.c | 445 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/vfpacket.w | 424 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/writecff.c (renamed from Build/source/texk/web2c/luatexdir/font/writecff.w) | 1917 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/writeenc.c (renamed from Build/source/texk/web2c/luatexdir/font/writeenc.w) | 70 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/writefont.c (renamed from Build/source/texk/web2c/luatexdir/font/writefont.w) | 673 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/writet1.c (renamed from Build/source/texk/web2c/luatexdir/font/writet1.w) | 738 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/writet3.c (renamed from Build/source/texk/web2c/luatexdir/font/writet3.w) | 69 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/writettf.c (renamed from Build/source/texk/web2c/luatexdir/font/writettf.w) | 1046 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/writetype0.c (renamed from Build/source/texk/web2c/luatexdir/font/writetype0.w) | 74 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/writetype2.c (renamed from Build/source/texk/web2c/luatexdir/font/writetype2.w) | 256 |
25 files changed, 7145 insertions, 7937 deletions
diff --git a/Build/source/texk/web2c/luatexdir/font/dofont.w b/Build/source/texk/web2c/luatexdir/font/dofont.c index b91bec10689..b23368d834f 100644 --- a/Build/source/texk/web2c/luatexdir/font/dofont.w +++ b/Build/source/texk/web2c/luatexdir/font/dofont.c @@ -1,42 +1,42 @@ -% dofont.w -% -% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org> -% -% This file is part of LuaTeX. -% -% LuaTeX 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. -% -% LuaTeX 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 Lesser General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License along -% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. - -@ @c +/* +Copyright 2006-2010 Taco Hoekwater <taco@luatex.org> + +This file is part of LuaTeX. + +LuaTeX 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. + +LuaTeX 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU General Public License along +with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +*/ #include "ptexlib.h" #include "lua/luatex-api.h" -@ a bit more interfacing is needed for proper error reporting +/*tex + + A bit more interfacing is needed for proper error reporting. + +*/ -@c static char *font_error_message(pointer u, char *nom, scaled s) { char *str = xmalloc(256); char *c = makecstring(cs_text(u)); const char *extra = "metric data not found or bad"; if (s >= 0) { - snprintf(str, 255, "Font \\%s=%s at %gpt not loadable: %s", c, nom, - (double) s / 65536, extra); + snprintf(str, 255, "Font \\%s=%s at %gpt not loadable: %s", c, nom, (double) s / 65536, extra); } else if (s != -1000) { - snprintf(str, 255, "Font \\%s=%s scaled %d not loadable: %s", c, nom, - (int) (-s), extra); + snprintf(str, 255, "Font \\%s=%s scaled %d not loadable: %s", c, nom, (int) (-s), extra); } else { snprintf(str, 255, "Font \\%s=%s not loadable: %s", c, nom, extra); } @@ -46,26 +46,22 @@ static char *font_error_message(pointer u, char *nom, scaled s) static int do_define_font(int f, const char *cnom, scaled s, int natural_dir) { - - boolean res; /* was the callback successful? */ - int callback_id; + boolean res = 0; char *cnam; int r, t; - res = 0; - - callback_id = callback_defined(define_font_callback); + int callback_id = callback_defined(define_font_callback); if (callback_id > 0) { cnam = xstrdup(cnom); callback_id = run_and_save_callback(callback_id, "Sdd->", cnam, s, f); free(cnam); - if (callback_id > 0) { /* success */ + if (callback_id > 0) { + /*tex Success. */ luaL_checkstack(Luas, 1, "out of stack space"); lua_rawgeti(Luas, LUA_REGISTRYINDEX, callback_id); t = lua_type(Luas, -1); if (t == LUA_TTABLE) { res = font_from_lua(Luas, f); destroy_saved_callback(callback_id); - /* |lua_pop(Luas, 1);| *//* done by |font_from_lua| */ } else if (t == LUA_TNUMBER) { r = (int) lua_tointeger(Luas, -1); destroy_saved_callback(callback_id); @@ -86,12 +82,16 @@ static int do_define_font(int f, const char *cnom, scaled s, int natural_dir) } } if (font_name(f) && strlen(font_name(f)) > 255) { - /* the font name has to fit in the dvi file's single byte storage */ - /* no need to test area, as we are never using it */ + /*tex + + The font name has to fit in the dvi file's single byte storage. There + is no need to test area, as we are never using it. + */ res = 0; } if (res) { - if (font_type(f) != virtual_font_type) { /* implies lua */ + if (font_type(f) != virtual_font_type) { + /*tex This implies \LUA. */ do_vf(f); set_font_natural_dir(f, natural_dir); } @@ -112,8 +112,8 @@ int read_font_info(pointer u, char *cnom, scaled s, int natural_dir) if ((f = do_define_font(f, cnom, s, natural_dir))) { return f; } else { - const char *help[] = - { "I wasn't able to read the size data for this font,", + const char *help[] = { + "I wasn't able to read the size data for this font,", "so I will ignore the font specification.", "[Wizards can fix TFM files using TFtoPL/PLtoTF.]", "You might try inserting a different font spec;", @@ -129,10 +129,6 @@ int read_font_info(pointer u, char *cnom, scaled s, int natural_dir) } } -@ TODO This function is a placeholder. There can easily appears holes in - the |font_tables| array, and we could attempt to reuse those - -@c int find_font_id(const char *nom, scaled s) { int f; diff --git a/Build/source/texk/web2c/luatexdir/font/luafont.w b/Build/source/texk/web2c/luatexdir/font/luafont.c index f63b71a1c15..e64aaffc15d 100644 --- a/Build/source/texk/web2c/luatexdir/font/luafont.w +++ b/Build/source/texk/web2c/luatexdir/font/luafont.c @@ -1,29 +1,34 @@ -% luafont.w -% -% Copyright 2006-2011 Taco Hoekwater <taco@@luatex.org> -% -% This file is part of LuaTeX. -% -% LuaTeX 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. -% -% LuaTeX 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 Lesser General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License along -% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. - -@ @c +/* + +Copyright 2006-2011 Taco Hoekwater <taco@luatex.org> + +This file is part of LuaTeX. + +LuaTeX 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. + +LuaTeX 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU General Public License along +with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +*/ + #include "ptexlib.h" #include "lua/luatex-api.h" #define noVERBOSE -/* todo: also keys */ +/*tex + + Todo: make these keys. + +*/ const char *font_type_strings[] = { "unknown", "virtual", "real", NULL @@ -116,8 +121,6 @@ const char *MATH_param_names[] = { NULL, }; -/* here for now, may be useful elsewhere */ - int ff_checkoption (lua_State *L, int narg, const char *def, const char *const lst[]); int ff_checkoption (lua_State *L, int narg, const char *def, const char *const lst[]) { @@ -170,13 +173,10 @@ static void font_char_to_lua(lua_State * L, internal_font_number f, charinfo * c { liginfo *l; kerninfo *ki; - lua_createtable(L, 0, 10); - dump_intfield(L,width,get_charinfo_width(co)); dump_intfield(L,height,get_charinfo_height(co)); dump_intfield(L,depth,get_charinfo_depth(co)); - if (get_charinfo_italic(co) != 0) { dump_intfield(L,italic,get_charinfo_italic(co)); } @@ -259,7 +259,7 @@ static void font_char_to_lua(lua_State * L, internal_font_number f, charinfo * c lua_createtable(L, 10, 1); for (i = 0; !kern_end(ki[i]); i++) { if (kern_disabled(ki[i])) { - /* skip like in lookup */ + /*tex Skip like in lookup. */ } else { lua_rawgeti(L, -1, kern_char(ki[i])); if (lua_type(L,-1) == LUA_TNIL) { @@ -272,7 +272,7 @@ static void font_char_to_lua(lua_State * L, internal_font_number f, charinfo * c lua_pushinteger(L, kern_kern(ki[i])); lua_rawset(L, -3); } else { - /* first one wins */ + /*tex The first one wins. */ lua_pop(L,1); } } @@ -301,48 +301,47 @@ static void font_char_to_lua(lua_State * L, internal_font_number f, charinfo * c } lua_rawset(L, -3); } - lua_push_string_by_name(L,mathkern); lua_newtable(L); { - int i, j; - i = get_charinfo_math_kerns(co, top_right_kern); - j = 0; - if (i > 0) { - j++; - lua_push_string_by_name(L,top_right); - lua_newtable(L); - dump_math_kerns(L, co, i, top_right_kern); - lua_rawset(L, -3); - } - i = get_charinfo_math_kerns(co, top_left_kern); - if (i > 0) { - j++; - lua_push_string_by_name(L,top_left); - lua_newtable(L); - dump_math_kerns(L, co, i, top_left_kern); - lua_rawset(L, -3); - } - i = get_charinfo_math_kerns(co, bottom_right_kern); - if (i > 0) { - j++; - lua_push_string_by_name(L,bottom_right); - lua_newtable(L); - dump_math_kerns(L, co, i, bottom_right_kern); - lua_rawset(L, -3); - } - i = get_charinfo_math_kerns(co, bottom_left_kern); - if (i > 0) { - j++; - lua_push_string_by_name(L,bottom_left); - lua_newtable(L); - dump_math_kerns(L, co, i, bottom_left_kern); - lua_rawset(L, -3); - } - if (j > 0) - lua_rawset(L, -3); - else - lua_pop(L, 2); + int i, j; + i = get_charinfo_math_kerns(co, top_right_kern); + j = 0; + if (i > 0) { + j++; + lua_push_string_by_name(L,top_right); + lua_newtable(L); + dump_math_kerns(L, co, i, top_right_kern); + lua_rawset(L, -3); + } + i = get_charinfo_math_kerns(co, top_left_kern); + if (i > 0) { + j++; + lua_push_string_by_name(L,top_left); + lua_newtable(L); + dump_math_kerns(L, co, i, top_left_kern); + lua_rawset(L, -3); + } + i = get_charinfo_math_kerns(co, bottom_right_kern); + if (i > 0) { + j++; + lua_push_string_by_name(L,bottom_right); + lua_newtable(L); + dump_math_kerns(L, co, i, bottom_right_kern); + lua_rawset(L, -3); + } + i = get_charinfo_math_kerns(co, bottom_left_kern); + if (i > 0) { + j++; + lua_push_string_by_name(L,bottom_left); + lua_newtable(L); + dump_math_kerns(L, co, i, bottom_left_kern); + lua_rawset(L, -3); + } + if (j > 0) + lua_rawset(L, -3); + else + lua_pop(L, 2); } } @@ -382,7 +381,6 @@ static void write_lua_parameters(lua_State * L, int f) lua_rawset(L, -3); } -@ @c static void write_lua_math_parameters(lua_State * L, int f) { int k; @@ -404,14 +402,12 @@ int font_to_lua(lua_State * L, int f) int k; charinfo *co; if (font_cache_id(f) > 0) { - /* fetch the table from the registry if it was - saved there by |font_from_lua()| */ + /*tex Fetch the table from the registry if it was saved there by |font_from_lua|. */ lua_rawgeti(L, LUA_REGISTRYINDEX, font_cache_id(f)); - /* fontdimens can be changed from tex code */ + /*tex Font dimenensions can be changed from \TEX\ code. */ write_lua_parameters(L, f); return 1; } - lua_newtable(L); lua_push_string_by_name(L,name); lua_pushstring(L, font_name(f)); @@ -431,7 +427,6 @@ int font_to_lua(lua_State * L, int f) if (font_encodingname(f) != NULL) { dump_stringfield(L,encodingname,font_encodingname(f)); } - dump_booleanfield(L,used,(font_used(f) ? true : false)); dump_stringfield(L,type,font_type_strings[font_type(f)]); dump_stringfield(L,format,font_format_strings[font_format(f)]); @@ -439,19 +434,20 @@ int font_to_lua(lua_State * L, int f) dump_stringfield(L,identity,font_identity_strings[font_identity(f)]); dump_stringfield(L,embedding,font_embedding_strings[font_embedding(f)]); dump_intfield(L,streamprovider,font_streamprovider(f)); - dump_intfield(L,units_per_em,font_units_per_em(f)); dump_intfield(L,size,font_size(f)); dump_intfield(L,designsize,font_dsize(f)); dump_intfield(L,checksum,font_checksum(f)); dump_intfield(L,slant,font_slant(f)); dump_intfield(L,extend,font_extend(f)); + dump_intfield(L,squeeze,font_squeeze(f)); + dump_intfield(L,mode,font_mode(f)); + dump_intfield(L,width,font_width(f)); dump_intfield(L,direction,font_natural_dir(f)); dump_intfield(L,encodingbytes,font_encodingbytes(f)); dump_booleanfield(L,oldmath,font_oldmath(f)); dump_intfield(L,tounicode,font_tounicode(f)); - - /* the next one is read only */ + /*tex The next one is read only: */ if (font_max_shrink(f) != 0) { dump_intfield(L,shrink,font_max_shrink(f)); } @@ -466,14 +462,12 @@ int font_to_lua(lua_State * L, int f) dump_stringfield(L,attributes,s); free(s); } - - /* params */ + /*tex Parameters: */ write_lua_parameters(L, f); write_lua_math_parameters(L, f); - - /* chars */ + /*tex Characters: */ lua_push_string_by_name(L,characters); - lua_createtable(L, font_tables[f]->charinfo_size, 0); /* all characters */ + lua_createtable(L, font_tables[f]->charinfo_size, 0); if (has_left_boundary(f)) { co = get_charinfo(f, left_boundarychar); lua_push_string_by_name(L,left_boundary); @@ -495,11 +489,11 @@ int font_to_lua(lua_State * L, int f) } } lua_rawset(L, -3); - - if (font_cache_id(f) == 0) { /* renew */ + if (font_cache_id(f) == 0) { + /*tex Renew the cache. */ int r; lua_pushvalue(L, -1); - r = luaL_ref(L, LUA_REGISTRYINDEX); /* pops the table */ + r = luaL_ref(L, LUA_REGISTRYINDEX); set_font_cache_id(f, r); } return 1; @@ -516,12 +510,11 @@ int font_to_lua(lua_State * L, int f) } \ } \ if (n) { \ - /* keep table on stack */ \ + /*tex Keep the table on stack. */ \ } else{ \ lua_pop(L, 1); \ } -@ @c #define streq(a,b) (strcmp(a,b)==0) #define append_packet(k) { *(cp++) = (eight_bits) (k); } @@ -533,7 +526,6 @@ int font_to_lua(lua_State * L, int f) append_packet((l & 0x000000FF)); \ } -@ @c static void append_float(eight_bits ** cpp, float a) { unsigned int i; @@ -553,7 +545,8 @@ static int n_enum_field(lua_State * L, int name_index, int dflt, const char **va int k, t; const char *s; int i = dflt; - lua_rawgeti(L, LUA_REGISTRYINDEX, name_index); /* fetch the stringptr */ + /*tex Fetch the string pointer: */ + lua_rawgeti(L, LUA_REGISTRYINDEX, name_index); lua_rawget(L, -2); t = lua_type(L,-1); if (t == LUA_TNUMBER) { @@ -576,7 +569,8 @@ static int n_enum_field(lua_State * L, int name_index, int dflt, const char **va static int n_boolean_field(lua_State * L, int name_index, int dflt) { int i = dflt; - lua_rawgeti(L, LUA_REGISTRYINDEX, name_index); /* fetch the stringptr */ + /*tex Fetch the string pointer: */ + lua_rawgeti(L, LUA_REGISTRYINDEX, name_index); lua_rawget(L, -2); if (lua_isboolean(L, -1)) { i = lua_toboolean(L, -1); @@ -588,7 +582,8 @@ static int n_boolean_field(lua_State * L, int name_index, int dflt) static char *n_string_field_copy(lua_State * L, int name_index, const char *dflt) { char *i; - lua_rawgeti(L, LUA_REGISTRYINDEX, name_index); /* fetch the stringptr */ + /*tex Fetch the string pointer: */ + lua_rawgeti(L, LUA_REGISTRYINDEX, name_index); lua_rawget(L, -2); if (lua_type(L,-1) == LUA_TSTRING) { i = xstrdup(lua_tostring(L, -1)); @@ -603,20 +598,20 @@ static char *n_string_field_copy(lua_State * L, int name_index, const char *dflt static const char *n_string_field(lua_State * L, int name_index) { - lua_rawgeti(L, LUA_REGISTRYINDEX, name_index); /* fetch the stringptr */ + /*tex Fetch the string pointer: */ + lua_rawgeti(L, LUA_REGISTRYINDEX, name_index); lua_rawget(L, -2); return lua_tostring(L,-1); } static int n_some_field(lua_State * L, int name_index) { - lua_rawgeti(L, LUA_REGISTRYINDEX, name_index); /* fetch the stringptr */ + /*tex Fetch the string pointer: */ + lua_rawgeti(L, LUA_REGISTRYINDEX, name_index); lua_rawget(L, -2); return lua_type(L,-1); } -/*static void init_font_string_pointers(lua_State * L){}*/ - static int count_char_packet_bytes(lua_State * L) { register int i; @@ -646,7 +641,7 @@ static int count_char_packet_bytes(lua_State * L) l++; } else if (lua_key_eq(s, rule)) { l += 9; - } else if (lua_key_eq(s, right) || lua_key_eq(s, node) || lua_key_eq(s, down) || lua_key_eq(s, image)) { + } else if (lua_key_eq(s, right) || lua_key_eq(s, node) || lua_key_eq(s, down) || lua_key_eq(s, image) || lua_key_eq(s, lua)) { l += 5; } else if (lua_key_eq(s, scale)) { l += sizeof(float) + 1; @@ -657,9 +652,9 @@ static int count_char_packet_bytes(lua_State * L) lua_rawgeti(L, -2, 2); if (ts == 3) { if (lua_type(L,-1) == LUA_TSTRING) { - /* no need to do something */ + /*tex There is no need to do something. */ } else if (lua_type(L,-1) == LUA_TNUMBER) { - /* no need to do something */ + /*tex There is no need to do something. */ } else { normal_error("vf command","invalid packet pdf literal category"); } @@ -674,7 +669,7 @@ static int count_char_packet_bytes(lua_State * L) normal_error("vf command","invalid packet pdf literal"); } lua_pop(L, ts == 3 ? 2 : 1); - } else if (lua_key_eq(s, special) || lua_key_eq(s, lua)) { + } else if (lua_key_eq(s, special)) { size_t len; lua_rawgeti(L, -2, 2); if (lua_type(L,-1) == LUA_TSTRING) { @@ -692,9 +687,11 @@ static int count_char_packet_bytes(lua_State * L) } else { normal_error("vf command","no packet command"); } - lua_pop(L, 1); /* command name */ + /*tex Pop the command name: */ + lua_pop(L, 1); } - lua_pop(L, 1); /* item */ + /*tex Pop this item: */ + lua_pop(L, 1); } return l; } @@ -707,7 +704,6 @@ static scaled sp_to_dvi(halfword sp, halfword atsize) return floor(result / mult); } -@ @c static void read_char_packets(lua_State * L, int *l_fonts, charinfo * co, internal_font_number f, int atsize) { int i, n, m; @@ -728,7 +724,7 @@ static void read_char_packets(lua_State * L, int *l_fonts, charinfo * co, intern for (i = 1; i <= (int) lua_rawlen(L, -1); i++) { lua_rawgeti(L, -1, i); if (lua_istable(L, -1)) { - /* fetch the command code */ + /*tex fetch the command code */ lua_rawgeti(L, -1, 1); if (lua_type(L,-1) == LUA_TSTRING) { s = lua_tostring(L, -1); @@ -743,7 +739,7 @@ static void read_char_packets(lua_State * L, int *l_fonts, charinfo * co, intern do_store_four(ff); } } else if (lua_key_eq(s, slot)) { - /* we could be sparse but no real reason */ + /*tex we could be sparse but no real reason */ cmd = packet_nop_code; lua_rawgeti(L, -2, 2); n = (int) lua_roundnumber(L, -1); @@ -804,7 +800,7 @@ static void read_char_packets(lua_State * L, int *l_fonts, charinfo * co, intern case packet_node_code: append_packet(cmd); lua_rawgeti(L, -2, 2); - n = copy_node_list(nodelist_from_lua(L)); + n = copy_node_list(nodelist_from_lua(L,-1)); do_store_four(n); lua_pop(L, 1); break; @@ -837,18 +833,18 @@ static void read_char_packets(lua_State * L, int *l_fonts, charinfo * co, intern ts = (int) lua_rawlen(L, -2); lua_rawgeti(L, -2, 2); if (ts == 3) { - /* mode on stack */ + /*tex mode on stack */ s = lua_tostring(L, -1); if (lua_type(L, -1) == LUA_TSTRING) { - /* <pdf> <mode> <direct|page|text|raw|origin> */ + /*tex |<pdf> <mode> <direct|page|text|raw|origin>| */ if (lua_key_eq(s, mode)) { cmd = packet_pdf_mode; lua_rawgeti(L, -3, 3); - /* mode on stack */ + /*tex mode on stack */ s = lua_tostring(L, -1); } } else { - /* <pdf> <direct|page|text|raw|origin> <string> */ + /*tex |<pdf> <direct|page|text|raw|origin> <string>| */ } if (lua_type(L, -1) == LUA_TSTRING) { if (lua_key_eq(s, direct)) { @@ -864,7 +860,6 @@ static void read_char_packets(lua_State * L, int *l_fonts, charinfo * co, intern } else if (lua_key_eq(s, origin)) { n = set_origin; } else { - /* normal_warning("vf command","invalid pdf literal type"); */ n = set_origin ; } } else { @@ -874,8 +869,8 @@ static void read_char_packets(lua_State * L, int *l_fonts, charinfo * co, intern } } if (cmd == packet_pdf_code) { + /*tex string on stack */ lua_rawgeti(L, -3, 3); - /* string on stack */ } } else { n = set_origin; @@ -897,7 +892,6 @@ static void read_char_packets(lua_State * L, int *l_fonts, charinfo * co, intern lua_pop(L,ts == 3 ? 2 : 1); break; case packet_special_code: - case packet_lua_code: append_packet(cmd); lua_rawgeti(L, -2, 2); s = luaL_checklstring(L, -1, &l); @@ -912,19 +906,25 @@ static void read_char_packets(lua_State * L, int *l_fonts, charinfo * co, intern } lua_pop(L, 1); break; + case packet_lua_code: + append_packet(cmd); + lua_rawgeti(L, -2, 2); + n = luaL_ref(L, LUA_REGISTRYINDEX); + do_store_four(n); + break; case packet_image_code: append_packet(cmd); - lua_rawgeti(L, -2, 2); /* img/imgtable? ... */ - if (lua_istable(L, -1)) { /* imgtable ... */ - lua_getglobal(L, "img"); /* imglib imgtable ... */ - lua_pushstring(L, "new"); /* `new' imglib imgtable ... */ - lua_gettable(L, -2); /* f imglib imgtable ... */ - lua_insert(L, -3); /* imglib imgtable f ... */ - lua_pop(L, 1); /* imgtable f ... */ + lua_rawgeti(L, -2, 2); + if (lua_istable(L, -1)) { + lua_getglobal(L, "img"); + lua_pushstring(L, "new"); + lua_gettable(L, -2); + lua_insert(L, -3); + lua_pop(L, 1); lua_call(L, 1, 1); - } /* img ... */ - luaL_checkudata(L, -1, TYPE_IMG); /* img ... --- just typecheck */ - n = luaL_ref(L, LUA_REGISTRYINDEX); /* ... */ + } + luaL_checkudata(L, -1, TYPE_IMG); + n = luaL_ref(L, LUA_REGISTRYINDEX); do_store_four(n); break; case packet_nop_code: @@ -937,34 +937,32 @@ static void read_char_packets(lua_State * L, int *l_fonts, charinfo * co, intern break; default: normal_error("vf command","invalid packet code"); - /* fprintf(stdout, "Unknown char packet code %s\n", s); */ } } - lua_pop(L, 1); /* command code */ + /*tex Command code: */ + lua_pop(L, 1); } else { normal_error("vf command","commands has to be a table"); - /* fprintf(stdout, "Found a `commands' item that is not a table\n"); */ } - lua_pop(L, 1); /* command table */ + /*tex Command table: */ + lua_pop(L, 1); } append_packet(packet_end_code); set_charinfo_packets(co, cpackets); return; } -@ @c static void read_lua_cidinfo(lua_State * L, int f) { int i; char *s; - /*lua_getfield(L, -1, "cidinfo");*/ lua_key_rawgeti(cidinfo); if (lua_istable(L, -1)) { i = lua_numeric_field_by_index(L,lua_key_index(version), 0); set_font_cidversion(f, i); i = lua_numeric_field_by_index(L,lua_key_index(supplement), 0); set_font_cidsupplement(f, i); - s = n_string_field_copy(L, lua_key_index(registry), "Adobe"); /* Adobe-Identity-0 */ + s = n_string_field_copy(L, lua_key_index(registry), "Adobe"); set_font_cidregistry(f, s); s = n_string_field_copy(L, lua_key_index(ordering), "Identity"); set_font_cidordering(f, s); @@ -972,38 +970,35 @@ static void read_lua_cidinfo(lua_State * L, int f) lua_pop(L, 1); } - -@ @c static void read_lua_parameters(lua_State * L, int f) { int i, n, t; const char *s; - /*lua_getfield(L, -1, "parameters");*/ lua_key_rawgeti(parameters); if (lua_istable(L, -1)) { - /* the number of parameters is the max(IntegerKeys(L)),7) */ + /*tex The number of parameters is the |max(IntegerKeys(L)),7)| */ n = 7; - lua_pushnil(L); /* first key */ + lua_pushnil(L); while (lua_next(L, -2) != 0) { if (lua_type(L, -2) == LUA_TNUMBER) { i = (int) lua_tointeger(L, -2); if (i > n) n = i; } - lua_pop(L, 1); /* pop value */ + lua_pop(L, 1); } if (n > 7) set_font_params(f, n); - /* sometimes it is handy to have all integer keys */ + /*tex Sometimes it is handy to have all integer keys: */ for (i = 1; i <= 7; i++) { lua_rawgeti(L, -1, i); if (lua_type(L, -1) == LUA_TNUMBER) { - n = lua_roundnumber(L, -1); /* round ? */ + n = lua_roundnumber(L, -1); set_font_param(f, i, n); } lua_pop(L, 1); } - lua_pushnil(L); /* first key */ + lua_pushnil(L); while (lua_next(L, -2) != 0) { t = lua_type(L,-2); if (t == LUA_TNUMBER) { @@ -1046,11 +1041,9 @@ static void read_lua_parameters(lua_State * L, int f) } -@ @c static void read_lua_math_parameters(lua_State * L, int f) { int i = 0, n = 0, t; - /*lua_getfield(L, -1, "MathConstants");*/ lua_key_rawgeti(MathConstants); if (lua_istable(L, -1)) { lua_pushnil(L); @@ -1065,7 +1058,7 @@ static void read_lua_math_parameters(lua_State * L, int f) if (i > 0) { set_font_math_param(f, i, n); } - lua_pop(L, 1); /* pop value */ + lua_pop(L, 1); } set_font_oldmath(f,false); } else { @@ -1074,7 +1067,6 @@ static void read_lua_math_parameters(lua_State * L, int f) lua_pop(L, 1); } -@ @c #define MIN_INF -0x7FFFFFFF static void store_math_kerns(lua_State * L, int index, charinfo * co, int id) @@ -1097,7 +1089,6 @@ static void store_math_kerns(lua_State * L, int index, charinfo * co, int id) lua_pop(L, 1); } -@ @c static void font_char_from_lua(lua_State * L, internal_font_number f, int i, int *l_fonts, boolean has_math) { int k, r, t, lt, u, n; @@ -1106,8 +1097,10 @@ static void font_char_from_lua(lua_State * L, internal_font_number f, int i, int liginfo *cligs; scaled j; const char *s; - int nl = 0; /* number of ligature table items */ - int nk = 0; /* number of kern table items */ + /*tex The number of ligature table items: */ + int nl = 0; + /*tex The number of kern table items: */ + int nk = 0; int ctr = 0; int atsize = font_size(f); if (lua_istable(L, -1)) { @@ -1138,7 +1131,7 @@ static void font_char_from_lua(lua_State * L, internal_font_number f, int i, int set_charinfo_name(co, xstrdup(s)); else set_charinfo_name(co, NULL); - /* n_string_field leaves a value on stack*/ + /*tex |n_string_field| leaves a value on stack*/ lua_pop(L,1); u = n_some_field(L,lua_key_index(tounicode)); if (u == LUA_TNUMBER) { @@ -1150,7 +1143,7 @@ static void font_char_from_lua(lua_State * L, internal_font_number f, int i, int sprintf(s,"%04X",(unsigned int) u); set_charinfo_tounicode(co,s); } else { - char *s = malloc(9); + char *s = malloc(11); u = u - 0x10000; sprintf(s,"%04X%04X",(unsigned int) (floor(u/1024)+0xD800),(unsigned int) (u%1024+0xDC00)); set_charinfo_tounicode(co,s); @@ -1203,9 +1196,7 @@ static void font_char_from_lua(lua_State * L, internal_font_number f, int i, int } else { set_charinfo_tounicode(co, NULL); } - /* ... leaves a value on stack*/ lua_pop(L,1); - if (has_math) { j = lua_numeric_field_by_index(L, lua_key_index(top_accent), INT_MIN); set_charinfo_top_accent(co, j); @@ -1216,7 +1207,6 @@ static void font_char_from_lua(lua_State * L, internal_font_number f, int i, int set_charinfo_tag(co, list_tag); set_charinfo_remainder(co, k); } - lua_key_rawgeti(extensible); if (lua_istable(L, -1)) { int top, bot, mid, rep; @@ -1232,7 +1222,6 @@ static void font_char_from_lua(lua_State * L, internal_font_number f, int i, int } } lua_pop(L, 1); - lua_key_rawgeti(horiz_variants); if (lua_istable(L, -1)) { int glyph, startconnect, endconnect, advance, extender; @@ -1257,7 +1246,6 @@ static void font_char_from_lua(lua_State * L, internal_font_number f, int i, int } } lua_pop(L, 1); - lua_key_rawgeti(vert_variants); if (lua_istable(L, -1)) { int glyph, startconnect, endconnect, advance, extender; @@ -1282,19 +1270,19 @@ static void font_char_from_lua(lua_State * L, internal_font_number f, int i, int } } lua_pop(L, 1); - - /* + /*tex Here is a complete example: - |mathkern = {| - | bottom_left = { { height = 420, kern = 80 }, { height = 520, kern = 4 } },| - | bottom_right = { { height = 0, kern = 48 } },| - | top_left = { { height = 620, kern = 0 }, { height = 720, kern = -80 } },| - | top_right = { { height = 676, kern = 115 }, { height = 776, kern = 45 } },| - |}| + \starttyping + mathkern = { + bottom_left = { { height = 420, kern = 80 }, { height = 520, kern = 4 } }, + bottom_right = { { height = 0, kern = 48 } }, + top_left = { { height = 620, kern = 0 }, { height = 720, kern = -80 } }, + top_right = { { height = 676, kern = 115 }, { height = 776, kern = 45 } }, + } + \stoptyping */ - lua_key_rawgeti(mathkern); if (lua_istable(L, -1)) { store_math_kerns(L,lua_key_index(top_left), co, top_left_kern); @@ -1304,18 +1292,20 @@ static void font_char_from_lua(lua_State * L, internal_font_number f, int i, int } lua_pop(L, 1); } - /* end of |has_math| */ + /*tex end of |has_math| */ count_hash_items(L, kerns, nk); if (nk > 0) { - /* kerns table still on stack */ + /*tex The kerns table is still on stack. */ ckerns = xcalloc((unsigned) (nk + 1), sizeof(kerninfo)); ctr = 0; - lua_pushnil(L); /* traverse hash */ + /*tex Traverse the hash. */ + lua_pushnil(L); while (lua_next(L, -2) != 0) { k = non_boundarychar; lt = lua_type(L,-2); if (lt == LUA_TNUMBER) { - k = (int) lua_tointeger(L, -2); /* adjacent char */ + /*tex Adjacent char: */ + k = (int) lua_tointeger(L, -2); if (k < 0) k = non_boundarychar; } else if (lt == LUA_TSTRING) { @@ -1326,7 +1316,7 @@ static void font_char_from_lua(lua_State * L, internal_font_number f, int i, int set_right_boundary(f, get_charinfo(f, right_boundarychar)); } } - j = lua_roundnumber(L, -1); /* movement */ + j = lua_roundnumber(L, -1); if (k != non_boundarychar) { set_kern_item(ckerns[ctr], k, j); ctr++; @@ -1335,7 +1325,7 @@ static void font_char_from_lua(lua_State * L, internal_font_number f, int i, int } lua_pop(L, 1); } - /* guard against empty tables */ + /*tex A guard against empty tables. */ if (ctr > 0) { set_kern_item(ckerns[ctr], end_kern, 0); set_charinfo_kerns(co, ckerns); @@ -1344,31 +1334,30 @@ static void font_char_from_lua(lua_State * L, internal_font_number f, int i, int } lua_pop(L, 1); } - - /* packet commands */ - + /*tex Packet commands. */ lua_key_rawgeti(commands); if (lua_istable(L, -1)) { - lua_pushnil(L); /* first key */ + lua_pushnil(L); if (lua_next(L, -2) != 0) { lua_pop(L, 2); read_char_packets(L, (int *) l_fonts, co, f, atsize); } } lua_pop(L, 1); - - /* ligatures */ + /*tex The ligatures. */ count_hash_items(L, ligatures, nl); if (nl > 0) { - /* ligatures table still on stack */ + /*tex The ligatures table still on stack. */ cligs = xcalloc((unsigned) (nl + 1), sizeof(liginfo)); ctr = 0; - lua_pushnil(L); /* traverse hash */ + /*tex Traverse the hash. */ + lua_pushnil(L); while (lua_next(L, -2) != 0) { k = non_boundarychar; lt = lua_type(L,-2); if (lt == LUA_TNUMBER) { - k = (int) lua_tointeger(L, -2); /* adjacent char */ + /*tex Adjacent char: */ + k = (int) lua_tointeger(L, -2); if (k < 0) { k = non_boundarychar; } @@ -1382,7 +1371,8 @@ static void font_char_from_lua(lua_State * L, internal_font_number f, int i, int } r = -1; if (lua_istable(L, -1)) { - r = lua_numeric_field_by_index(L, lua_key_index(char), -1); /* ligature */ + /*tex Ligature: */ + r = lua_numeric_field_by_index(L, lua_key_index(char), -1); } if (r != -1 && k != non_boundarychar) { t = n_enum_field(L, lua_key_index(type), 0, ligature_type_strings); @@ -1391,67 +1381,66 @@ static void font_char_from_lua(lua_State * L, internal_font_number f, int i, int } else { formatted_warning("font", "lua-loaded font %s char U+%X has an invalid ligature field", font_name(f), (int) i); } - lua_pop(L, 1); /* iterator value */ + /*tex The iterator value: */ + lua_pop(L, 1); } - /* guard against empty tables */ + /*tex A guard against empty tables. */ if (ctr > 0) { set_ligature_item(cligs[ctr], 0, end_ligature, 0); set_charinfo_ligatures(co, cligs); } else { formatted_warning("font", "lua-loaded font %s char U+%X has an invalid ligatures field", font_name(f), (int) i); } - lua_pop(L, 1); /* ligatures table */ + /*tex The ligatures table. */ + lua_pop(L, 1); } } } -@ The caller has to fix the state of the lua stack when there is an error! +/*tex + + The caller has to fix the state of the lua stack when there is an error! + +*/ -@c int font_from_lua(lua_State * L, int f) { int i, n, r, t, lt; - int s_top; /* lua stack top */ - int bc; /* first char index */ - int ec; /* last char index */ + int s_top; + int bc; + int ec; char *s; const char *ss; int *l_fonts = NULL; int save_ref ; boolean no_math = false; - - /* will we save a cache of the luat table? */ - - save_ref = 1; /* we start with ss = "yes" */ + /*tex Will we save a cache of the \LUA\ table? */ + save_ref = 1; ss = NULL; ss = n_string_field(L, lua_key_index(cache)); if (lua_key_eq(ss, no)) save_ref = -1; else if (lua_key_eq(ss, renew)) save_ref = 0; - /* n_string_field leaves a value on stack*/ + /*tex |n_string_field| leaves a value on stack. */ lua_pop(L,1); - - /* the table is at stack index -1 */ + /*tex The table is at stack |index -1| */ s = n_string_field_copy(L,lua_key_index(area), ""); set_font_area(f, s); s = n_string_field_copy(L, lua_key_index(filename), NULL); set_font_filename(f, s); s = n_string_field_copy(L, lua_key_index(encodingname), NULL); set_font_encodingname(f, s); - s = n_string_field_copy(L, lua_key_index(name), NULL); set_font_name(f, s); s = n_string_field_copy(L, lua_key_index(fullname), font_name(f)); set_font_fullname(f, s); - if (s == NULL) { formatted_error("font","lua-loaded font '%d' has no name!", f); return false; } s = n_string_field_copy(L, lua_key_index(psname), NULL); set_font_psname(f, s); - i = lua_numeric_field_by_index(L,lua_key_index(units_per_em), 0); set_font_units_per_em(f, i); i = lua_numeric_field_by_index(L,lua_key_index(designsize), 655360); @@ -1469,34 +1458,48 @@ int font_from_lua(lua_State * L, int f) set_font_oldmath(f, i); i = lua_numeric_field_by_index(L,lua_key_index(tounicode), 0); set_font_tounicode(f, (char) i); - - i = lua_numeric_field_by_index(L,lua_key_index(extend), 1000); - if (i < FONT_EXTEND_MIN) - i = FONT_EXTEND_MIN; - if (i > FONT_EXTEND_MAX) - i = FONT_EXTEND_MAX; - set_font_extend(f, i); i = lua_numeric_field_by_index(L,lua_key_index(slant), 0); if (i < FONT_SLANT_MIN) i = FONT_SLANT_MIN; if (i > FONT_SLANT_MAX) i = FONT_SLANT_MAX; set_font_slant(f, i); - + i = lua_numeric_field_by_index(L,lua_key_index(extend), 1000); + if (i < FONT_EXTEND_MIN) + i = FONT_EXTEND_MIN; + if (i > FONT_EXTEND_MAX) + i = FONT_EXTEND_MAX; + set_font_extend(f, i); + i = lua_numeric_field_by_index(L,lua_key_index(squeeze), 1000); + if (i < FONT_SQUEEZE_MIN) + i = FONT_SQUEEZE_MIN; + if (i > FONT_SQUEEZE_MAX) + i = FONT_SQUEEZE_MAX; + set_font_squeeze(f, i); + i = lua_numeric_field_by_index(L,lua_key_index(width), 0); + if (i < FONT_WIDTH_MIN) + i = FONT_WIDTH_MIN; + if (i > FONT_WIDTH_MAX) + i = FONT_WIDTH_MAX; + set_font_width(f, i); + i = lua_numeric_field_by_index(L,lua_key_index(mode), 0); + if (i < FONT_MODE_MIN) + i = FONT_MODE_MIN; + if (i > FONT_MODE_MAX) + i = FONT_MODE_MAX; + set_font_mode(f, i); i = lua_numeric_field_by_index(L,lua_key_index(hyphenchar), default_hyphen_char_par); set_hyphen_char(f, i); i = lua_numeric_field_by_index(L,lua_key_index(skewchar), default_skew_char_par); set_skew_char(f, i); i = n_boolean_field(L, lua_key_index(used), 0); set_font_used(f, (char) i); - s = n_string_field_copy(L, lua_key_index(attributes), NULL); if (s != NULL && strlen(s) > 0) { i = maketexstring(s); set_pdf_font_attr(f, i); } free(s); - i = n_enum_field(L, lua_key_index(type), unknown_font_type, font_type_strings); set_font_type(f, i); i = n_enum_field(L, lua_key_index(format), unknown_format, font_format_strings); @@ -1510,11 +1513,10 @@ int font_from_lua(lua_State * L, int f) if (font_encodingbytes(f) == 0 && (font_format(f) == opentype_format || font_format(f) == truetype_format)) { set_font_encodingbytes(f, 2); } - - /* now fetch the base fonts, if needed */ + /*tex Now fetch the base fonts, if needed. */ count_hash_items(L, fonts, n); if (n > 0) { - /* font table still on stack */ + /*tex The font table still on stack. */ l_fonts = xmalloc((unsigned) ((unsigned) (n + 2) * sizeof(int))); memset(l_fonts, 0, (size_t) ((unsigned) (n + 2) * sizeof(int))); for (i = 1; i <= n; i++) { @@ -1526,20 +1528,22 @@ int font_from_lua(lua_State * L, int f) if (l_fonts[i] == 0) { l_fonts[i] = (int) f; } - lua_pop(L, 2); /* pop id and entry */ + /*tex Pop id and entry. */ + lua_pop(L, 2); continue; } - lua_pop(L, 1); /* pop id */ + /*tex Pop id. */ + lua_pop(L, 1); }; ss = NULL; if (lua_istable(L, -1)) { ss = n_string_field(L, lua_key_index(name)); - /* string is anchored */ + /*tex The string is anchored. */ lua_pop(L,1); } if (ss != NULL) { t = lua_numeric_field_by_index(L, lua_key_index(size), -1000); - /* TODO: the stack is messed up, otherwise this explicit resizing would not be needed */ + /*tex The stack is messed up, otherwise this explicit resizing would not be needed! */ s_top = lua_gettop(L); if (strcmp(font_name(f), ss) == 0) l_fonts[i] = f; @@ -1549,18 +1553,26 @@ int font_from_lua(lua_State * L, int f) } else { formatted_error("font","invalid local font at index %i in lua-loaded font '%s' (1)",i,font_name(f)); } - lua_pop(L, 1); /* pop list entry */ + /*tex Pop the list entry. */ + lua_pop(L, 1); } - lua_pop(L, 1); /* pop font table */ + /*tex Pop the font table. */ + lua_pop(L, 1); } else if (font_type(f) == virtual_font_type) { + /*tex + We no longer do this check but instead create an entry. This permits + (valid) tricks. + */ + /* formatted_error("font","invalid local fonts in lua-loaded font '%s' (2)", font_name(f)); + */ } else { l_fonts = xmalloc(3 * sizeof(int)); l_fonts[0] = 0; l_fonts[1] = f; l_fonts[2] = 0; } - /* parameters */ + /*tex The parameters. */ no_math = n_boolean_field(L, lua_key_index(nomath), 0); read_lua_parameters(L, f); if (!no_math) { @@ -1573,15 +1585,15 @@ int font_from_lua(lua_State * L, int f) set_font_oldmath(f,true); } read_lua_cidinfo(L, f); - - /* characters */ + /*tex The characters. */ lua_key_rawgeti(characters); if (lua_istable(L, -1)) { - /* find the array size values */ - int num = 0; /* number of charinfo's to add */ + /*tex Find the array size values; |num| holds the number of characters to add. */ + int num = 0; ec = 0; bc = -1; - lua_pushnil(L); /* first key */ + /*tex The first key: */ + lua_pushnil(L); while (lua_next(L, -2) != 0) { if (lua_isnumber(L, -2)) { i = (int) lua_tointeger(L, -2); @@ -1600,10 +1612,12 @@ int font_from_lua(lua_State * L, int f) lua_pop(L, 1); } if (bc != -1) { + int fstep; font_malloc_charinfo(f, num); set_font_bc(f, bc); set_font_ec(f, ec); - lua_pushnil(L); /* first key */ + /*tex The first key: */ + lua_pushnil(L); while (lua_next(L, -2) != 0) { lt = lua_type(L,-2); if (lt == LUA_TNUMBER) { @@ -1622,53 +1636,50 @@ int font_from_lua(lua_State * L, int f) lua_pop(L, 1); } lua_pop(L, 1); + /*tex - /* Handle font expansion last: the |copy_font| routine is called eventually, - and that needs to know |bc| and |ec|. - */ + and that needs to know |bc| and |ec|. We permits virtual fonts to use + expansion as one can always turn it off. - if (font_type(f) != virtual_font_type) { - int fstep = lua_numeric_field_by_index(L, lua_key_index(step), 0); - if (fstep < 0) - fstep = 0; - if (fstep > 100) - fstep = 100; - if (fstep != 0) { - int fshrink = lua_numeric_field_by_index(L, lua_key_index(shrink), 0); - int fstretch =lua_numeric_field_by_index(L, lua_key_index(stretch), 0); - if (fshrink < 0) - fshrink = 0; - if (fshrink > 500) - fshrink = 500; - fshrink -= (fshrink % fstep); - if (fshrink < 0) - fshrink = 0; - if (fstretch < 0) - fstretch = 0; - if (fstretch > 1000) - fstretch = 1000; - fstretch -= (fstretch % fstep); - if (fstretch < 0) - fstretch = 0; - set_expand_params(f, fstretch, fshrink, fstep); - } + */ + fstep = lua_numeric_field_by_index(L, lua_key_index(step), 0); + if (fstep < 0) + fstep = 0; + if (fstep > 100) + fstep = 100; + if (fstep != 0) { + int fshrink = lua_numeric_field_by_index(L, lua_key_index(shrink), 0); + int fstretch= lua_numeric_field_by_index(L, lua_key_index(stretch), 0); + if (fshrink < 0) + fshrink = 0; + if (fshrink > 500) + fshrink = 500; + fshrink -= (fshrink % fstep); + if (fshrink < 0) + fshrink = 0; + if (fstretch < 0) + fstretch = 0; + if (fstretch > 1000) + fstretch = 1000; + fstretch -= (fstretch % fstep); + if (fstretch < 0) + fstretch = 0; + set_expand_params(f, fstretch, fshrink, fstep); } } else { - /* jikes, no characters */ formatted_warning("font","lua-loaded font '%d' with name '%s' has no characters", f, font_name(f)); } - if (save_ref > 0) { - r = luaL_ref(L, LUA_REGISTRYINDEX); /* pops the table */ + /*tex This pops the table. */ + r = luaL_ref(L, LUA_REGISTRYINDEX); set_font_cache_id(f, r); } else { lua_pop(L, 1); set_font_cache_id(f, save_ref); } } else { - /* jikes, no characters */ formatted_warning("font","lua-loaded font '%d' with name '%s' has no character table", f, font_name(f)); } if (l_fonts != NULL) @@ -1683,15 +1694,15 @@ int characters_from_lua(lua_State * L, int f) int s_top; const char *ss; boolean no_math = false; - /* speedup */ + /*tex Speedup: */ no_math = n_boolean_field(L, lua_key_index(nomath), 0); - /* type */ + /*tex Type: */ i = n_enum_field(L, lua_key_index(type), font_type(f), font_type_strings); set_font_type(f, i); - /* fonts */ + /*tex Fonts: */ count_hash_items(L, fonts, n); if (n > 0) { - /* font table still on stack */ + /*tex The font table still on stack. */ l_fonts = xmalloc((unsigned) ((unsigned) (n + 2) * sizeof(int))); memset(l_fonts, 0, (size_t) ((unsigned) (n + 2) * sizeof(int))); for (i = 1; i <= n; i++) { @@ -1703,10 +1714,12 @@ int characters_from_lua(lua_State * L, int f) if (l_fonts[i] == 0) { l_fonts[i] = (int) f; } - lua_pop(L, 2); /* pop id and entry */ + /*tex Pop id and entry. */ + lua_pop(L, 2); continue; } - lua_pop(L, 1); /* pop id */ + /*tex Pop id. */ + lua_pop(L, 1); }; ss = NULL; if (lua_istable(L, -1)) { @@ -1716,7 +1729,7 @@ int characters_from_lua(lua_State * L, int f) } if (ss != NULL) { t = lua_numeric_field_by_index(L, lua_key_index(size), -1000); - /* TODO: the stack is messed up, otherwise this explicit resizing would not be needed */ + /*tex the stack is messed up, otherwise this explicit resizing would not be needed! */ s_top = lua_gettop(L); if (strcmp(font_name(f), ss) == 0) l_fonts[i] = f; @@ -1726,9 +1739,11 @@ int characters_from_lua(lua_State * L, int f) } else { formatted_error("font","invalid local font in lua-loaded font '%s' (3)", font_name(f)); } - lua_pop(L, 1); /* pop list entry */ + /*tex Pop list entry. */ + lua_pop(L, 1); } - lua_pop(L, 1); /* pop font table */ + /*tex Pop font table. */ + lua_pop(L, 1); } else if (font_type(f) == virtual_font_type) { formatted_error("font","invalid local fonts in lua-loaded font '%s' (4)", font_name(f)); } else { @@ -1737,15 +1752,16 @@ int characters_from_lua(lua_State * L, int f) l_fonts[1] = f; l_fonts[2] = 0; } - /* characters */ + /*tex The characters. */ lua_key_rawgeti(characters); if (lua_istable(L, -1)) { - /* find the array size values */ - int num = 0; /* number of charinfo's to add */ + /*tex Find the array size values; |num| has the amount. */ + int num = 0; int todo = 0; int bc = font_bc(f); int ec = font_ec(f); - lua_pushnil(L); /* first key */ + /*tex First key: */ + lua_pushnil(L); while (lua_next(L, -2) != 0) { if (lua_isnumber(L, -2)) { i = (int) lua_tointeger(L, -2); @@ -1770,7 +1786,8 @@ int characters_from_lua(lua_State * L, int f) font_malloc_charinfo(f, num); set_font_bc(f, bc); set_font_ec(f, ec); - lua_pushnil(L); /* first key */ + /*tex First key: */ + lua_pushnil(L); while (lua_next(L, -2) != 0) { lt = lua_type(L,-2); if (lt == LUA_TNUMBER) { @@ -1799,9 +1816,8 @@ int characters_from_lua(lua_State * L, int f) return true; } -@* Ligaturing. +/*tex Ligaturing starts here */ -@c static void nesting_append(halfword nest1, halfword newn) { halfword tail = tlink(nest1); @@ -1863,9 +1879,9 @@ static int try_ligature(halfword * frst, halfword fwd) font(newgl) = font(cur); character(newgl) = lig_replacement(lig); set_is_ligature(newgl); - /* - below might not be correct in contrived border case. - but we use it only for debugging, so ... + /*tex + Below might not be correct in contrived border case. but we use it + only for debugging. */ if (character(cur) < 0) { set_is_leftboundary(newgl); @@ -1884,13 +1900,13 @@ static int try_ligature(halfword * frst, halfword fwd) add_node_attr_ref(node_attr(cur)); node_attr(newgl) = node_attr(cur); } - - /* - TODO/FIXME if this ligature is consists of another ligature - we should add it's |lig_ptr| to the new glyphs |lig_ptr| (and - cleanup the no longer needed node) LOW PRIORITY + /*tex + Maybe if this ligature is consists of another ligature we should add + it's |lig_ptr| to the new glyphs |lig_ptr| (and cleanup the no longer + needed node). This has a very low priority, so low that it might + never happen. */ - /* left side */ + /*tex Left side: */ if (keep_left) { halfword new_first = copy_node(cur); lig_ptr(newgl) = new_first; @@ -1906,10 +1922,10 @@ static int try_ligature(halfword * frst, halfword fwd) couple_nodes(prev, newgl); cur = newgl; /* as cur has disappeared */ } - /* right side */ + /*tex Right side: */ if (keep_right) { halfword new_second = copy_node(fwd); - /* correct, because we {\it know\/} |lig_ptr| points to {\it one\/} node */ + /*tex This is correct, because we {\em know} |lig_ptr| points to {\em one} node. */ couple_nodes(lig_ptr(newgl), new_second); couple_nodes(newgl, fwd); if (move_after) { @@ -1919,24 +1935,27 @@ static int try_ligature(halfword * frst, halfword fwd) } else { halfword next = vlink(fwd); uncouple_node(fwd); - /* correct, because we {\it know\/} |lig_ptr| points to {\it one\/} node */ + /*tex This works because we {\em know} |lig_ptr| points to {\em one} node. */ couple_nodes(lig_ptr(newgl), fwd); if (next != null) { couple_nodes(newgl, next); } } - /* check and return */ + /*tex Check and return. */ *frst = cur; return 1; } return 0; } -@ there shouldn't be any ligatures here - we only add them at the end of - |xxx_break| in a \.{DISC-1 - DISC-2} situation and we stop processing \.{DISC-1} - (we continue with \.{DISC-1}'s |post_| and |no_break|. +/*tex + + There shouldn't be any ligatures here - we only add them at the end of + |xxx_break| in a \.{DISC-1 - DISC-2} situation and we stop processing + \.{DISC-1} (we continue with \.{DISC-1}'s |post_| and |no_break|. + +*/ -@c static halfword handle_lig_nest(halfword root, halfword cur) { if (cur == null) @@ -1959,7 +1978,7 @@ static halfword handle_lig_word(halfword cur) if (type(cur) == boundary_node) { halfword prev = alink(cur); halfword fwd = vlink(cur); - /* no need to uncouple |cur|, it is freed */ + /*tex There is no need to uncouple |cur|, it is freed. */ flush_node(cur); if (fwd == null) { vlink(prev) = fwd; @@ -1980,80 +1999,82 @@ static halfword handle_lig_word(halfword cur) right = new_glyph(font(cur), right_boundarychar); } while (1) { - /* A glyph followed by ... */ + /*tex A glyph followed by \unknown */ if (type(cur) == glyph_node) { halfword fwd = vlink(cur); - if (fwd == null) { /* last character of paragraph */ + if (fwd == null) { + /*tex The last character of a paragraph. */ if (right == null) break; - /* \.{--\\par} prohibits use of |couple_nodes| here */ + /*tex |par| prohibits the use of |couple_nodes| here. */ try_couple_nodes(cur, right); right = null; continue; } - if (type(fwd) == glyph_node) { /* |GLYPH - GLYPH| */ + if (type(fwd) == glyph_node) { + /*tex a glyph followed by a glyph */ if (font(cur) != font(fwd)) break; if (try_ligature(&cur, fwd)) continue; - } else if (type(fwd) == disc_node) { /* |GLYPH - DISC| */ - - /* if \.{a{bx}{}{y}} and \.{a+b=>B} convert to \.{{Bx}{}{ay}} */ + } else if (type(fwd) == disc_node) { + /*tex a glyph followed by a disc */ halfword pre = vlink_pre_break(fwd); halfword nob = vlink_no_break(fwd); halfword next, tail; liginfo lig; - /* Check on: a{b?}{?}{?} and a+b=>B : {B?}{?}{a?} */ - /* Check on: a{?}{?}{b?} and a+b=>B : {a?}{?}{B?} */ - if ((pre != null && type(pre) == glyph_node - && test_ligature(&lig, cur, pre)) - || (nob != null && type(nob) == glyph_node - && test_ligature(&lig, cur, nob))) { - /* move cur from before disc, to skipped part */ + /*tex Check on: |a{b?}{?}{?}| and |a+b=>B| : |{B?}{?}{a?}| */ + /*tex Check on: |a{?}{?}{b?}| and |a+b=>B| : |{a?}{?}{B?}| */ + if ((pre != null && type(pre) == glyph_node && test_ligature(&lig, cur, pre)) + || (nob != null && type(nob) == glyph_node && test_ligature(&lig, cur, nob))) { + /*tex Move |cur| from before disc to skipped part */ halfword prev = alink(cur); uncouple_node(cur); couple_nodes(prev, fwd); nesting_prepend(no_break(fwd), cur); - /* now ligature the |pre_break| */ + /*tex Now ligature the |pre_break|. */ nesting_prepend(pre_break(fwd), copy_node(cur)); - /* As we have removed cur, we need to start again ... */ + /*tex As we have removed cur, we need to start again. */ cur = prev; } - /* Check on: a{?}{?}{}b and a+b=>B : {a?}{?b}{B} */ + /*tex Check on: |a{?}{?}{}b| and |a+b=>B| : |{a?}{?b}{B}|. */ next = vlink(fwd); - if (nob == null && next != null && type(next) == glyph_node - && test_ligature(&lig, cur, next)) { - /* move |cur| from before |disc| to |no_break| part */ + if (nob == null && next != null && type(next) == glyph_node && test_ligature(&lig, cur, next)) { + /*tex Move |cur| from before |disc| to |no_break| part. */ halfword prev = alink(cur); uncouple_node(cur); couple_nodes(prev, fwd); - couple_nodes(no_break(fwd), cur); /* we {\it know\/} it's empty */ - /* now copy cur the |pre_break| */ + /*tex We {\em know} it's empty. */ + couple_nodes(no_break(fwd), cur); + /*tex Now copy |cur| the |pre_break|. */ nesting_prepend(pre_break(fwd), copy_node(cur)); - /* move next from after disc to |no_break| part */ + /*tex Move next from after disc to |no_break| part. */ tail = vlink(next); uncouple_node(next); try_couple_nodes(fwd, tail); - couple_nodes(cur, next); /* we {\it know\/} this works */ - tlink(no_break(fwd)) = next; /* and make sure the list is correct */ - /* now copy next to the |post_break| */ + /*tex We {\em know} this works. */ + couple_nodes(cur, next); + /*tex Make sure the list is correct. */ + tlink(no_break(fwd)) = next; + /*tex Now copy next to the |post_break|. */ nesting_append(post_break(fwd), copy_node(next)); - /* As we have removed cur, we need to start again ... */ + /*tex As we have removed cur, we need to start again. */ cur = prev; } - /* we are finished with the |pre_break| */ + /*tex We are finished with the |pre_break|. */ handle_lig_nest(pre_break(fwd), vlink_pre_break(fwd)); } else if (type(fwd) == boundary_node) { halfword next = vlink(fwd); try_couple_nodes(cur, next); flush_node(fwd); if (right != null) { - flush_node(right); /* Shame, didn't need it */ - /* no need to reset |right|, we're going to leave the loop anyway */ + /*tex Shame, didn't need it. */ + flush_node(right); + /*tex No need to reset |right|, we're going to leave the loop anyway. */ } break; } else { - /* fwd is something unknown */ + /*tex Is something unknown. */ if (right == null) break; couple_nodes(cur, right); @@ -2061,9 +2082,9 @@ static halfword handle_lig_word(halfword cur) right = null; continue; } - /* A discretionary followed by ... */ + /*tex A discretionary followed by \unknown */ } else if (type(cur) == disc_node) { - /* If \.{{?}{x}{?}} or \.{{?}{?}{y}} then ... */ + /*tex If |{?}{x}{?}| or |{?}{?}{y}| then: */ if (vlink_no_break(cur) != null || vlink_post_break(cur) != null) { halfword prev = 0; halfword fwd; @@ -2131,35 +2152,32 @@ static halfword handle_lig_word(halfword cur) && type(next) == glyph_node && ((tlink_post_break(cur) != null && test_ligature(&lig, tlink_post_break(cur), next)) || (tlink_no_break (cur) != null && test_ligature(&lig, tlink_no_break (cur), next)))) { - /* Building an |init_disc| followed by a |select_disc| - \.{{a-}{b}{AB} {-}{}{}} 'c' - */ - /* is it tail necessary ? */ - halfword last1 = vlink(next), tail ; + /*tex Building an |init_disc| followed by a |select_disc|: |{a-}{b}{AB} {-}{}{} c| */ + halfword last1 = vlink(next), tail; uncouple_node(next); try_couple_nodes(fwd, last1); - /* \.{{a-}{b}{AB} {-}{c}{}} */ + /*tex |{a-}{b}{AB} {-}{c}{}| */ nesting_append(post_break(fwd), copy_node(next)); - /* \.{{a-}{b}{AB} {-}{c}{-}} */ + /*tex |{a-}{b}{AB} {-}{c}{-}| */ if (vlink_no_break(cur) != null) { nesting_prepend(no_break(fwd), copy_node(vlink_pre_break(fwd))); } - /* \.{{a-}{b}{AB} {b-}{c}{-}} */ + /*tex |{a-}{b}{AB} {b-}{c}{-}| */ if (vlink_post_break(cur) != null) nesting_prepend_list(pre_break(fwd), copy_node_list(vlink_post_break(cur))); - /* \.{{a-}{b}{AB} {b-}{c}{AB-}} */ + /*tex |{a-}{b}{AB} {b-}{c}{AB-}| */ if (vlink_no_break(cur) != null) { nesting_prepend_list(no_break(fwd), copy_node_list(vlink_no_break(cur))); } - /* \.{{a-}{b}{ABC} {b-}{c}{AB-}} */ + /*tex |{a-}{b}{ABC} {b-}{c}{AB-}| */ tail = tlink_no_break(cur); nesting_append(no_break(cur), copy_node(next)); handle_lig_nest(no_break(cur), tail); - /* \.{{a-}{BC}{ABC} {b-}{c}{AB-}} */ + /*tex |{a-}{BC}{ABC} {b-}{c}{AB-}| */ tail = tlink_post_break(cur); nesting_append(post_break(cur), next); handle_lig_nest(post_break(cur), tail); - /* and set the subtypes */ + /*tex Set the subtypes: */ subtype(cur) = init_disc; subtype(fwd) = select_disc; } @@ -2167,39 +2185,33 @@ static halfword handle_lig_word(halfword cur) } } else { - /* NO GLYPH NOR DISC */ + /*tex We have glyph nor disc. */ return cur; } - /* step-to-next-node */ - /* \.{--\\par} allows |vlink(cur)| to be null */ + /*tex Goto the next node, where |\par| allows |vlink(cur)| to be NULL. */ cur = vlink(cur); } - return cur; } -@ Return value is the new tail, head should be a dummy +/*tex The return value is the new tail, head should be a dummy: */ -@c halfword handle_ligaturing(halfword head, halfword tail) { - halfword save_tail1 = null; /* trick to allow explicit |node==null| tests */ + /*tex A trick to allow explicit |node==null| tests. */ + halfword save_tail1 = null; halfword cur, prev; - if (vlink(head) == null) return tail; if (tail != null) { save_tail1 = vlink(tail); vlink(tail) = null; } - if (fix_node_lists) { fix_node_list(head); } - prev = head; cur = vlink(prev); - while (cur != null) { if (type(cur) == glyph_node || (type(cur) == boundary_node)) { cur = handle_lig_word(cur); @@ -2208,10 +2220,8 @@ halfword handle_ligaturing(halfword head, halfword tail) cur = vlink(cur); } if (prev == null) { - /* hh: looks bad to me */ prev = tail; } - if (tail != null) { try_couple_nodes(prev, save_tail1); } @@ -2219,9 +2229,8 @@ halfword handle_ligaturing(halfword head, halfword tail) } -@* Kerning. +/*tex Kerning starts here: */ -@c static void add_kern_before(halfword left, halfword right) { if ((!is_rightghost(right)) && @@ -2232,7 +2241,7 @@ static void add_kern_before(halfword left, halfword right) halfword prev = alink(right); couple_nodes(prev, kern); couple_nodes(kern, right); - /* update the attribute list (inherit from left) */ + /*tex Update the attribute list (inherit from left): */ delete_attribute_ref(node_attr(kern)); add_node_attr_ref(node_attr(left)); node_attr(kern) = node_attr(left); @@ -2250,7 +2259,7 @@ static void add_kern_after(halfword left, halfword right, halfword aft) halfword next = vlink(aft); couple_nodes(aft, kern); try_couple_nodes(kern, next); - /* update the attribute list (inherit from left == aft) */ + /*tex Update the attribute list (inherit from left == aft): */ delete_attribute_ref(node_attr(kern)); add_node_attr_ref(node_attr(aft)); node_attr(kern) = node_attr(aft); @@ -2298,7 +2307,7 @@ static void do_handle_kerning(halfword root, halfword init_left, halfword init_r tlink_post_break(cur) = tail_of_list(vlink_post_break(cur)); do_handle_kerning(no_break(cur), left, right); if (vlink_no_break(cur) != null) - tlink_no_break(cur) = tail_of_list(vlink_no_break(cur)); /* needed? */ + tlink_no_break(cur) = tail_of_list(vlink_no_break(cur)); } if (left != null) { if (character(left) < 0 || is_ghost(left)) { @@ -2331,22 +2340,6 @@ static void do_handle_kerning(halfword root, halfword init_left, halfword init_r } } -/* -halfword handle_kerning(halfword head, halfword tail) -{ - halfword save_link; - save_link = vlink(tail); - vlink(tail) = null; - tlink(head) = tail; - do_handle_kerning(head, null, null); - tail = tlink(head); - if (valid_node(save_link)) { - try_couple_nodes(tail, save_link); - } - return tail; -} -*/ - halfword handle_kerning(halfword head, halfword tail) { halfword save_link = null; @@ -2366,20 +2359,21 @@ halfword handle_kerning(halfword head, halfword tail) return tail; } -@* ligaturing and kerning : lua-interface. +/*tex The ligaturing and kerning \LUA\ interface: */ -@c static halfword run_lua_ligkern_callback(halfword head, halfword tail, int callback_id) { int i; int top = lua_gettop(Luas); if (!get_callback(Luas, callback_id)) { - lua_pop(Luas, 2); + lua_settop(Luas, top); return tail; } nodelist_to_lua(Luas, head); nodelist_to_lua(Luas, tail); if ((i=lua_pcall(Luas, 2, 0, 0)) != 0) { + formatted_warning("ligkern","error: %s",lua_tostring(Luas, -1)); + lua_settop(Luas, top); luatex_error(Luas, (i == LUA_ERRRUN ? 0 : 1)); return tail; } diff --git a/Build/source/texk/web2c/luatexdir/font/mapfile.c b/Build/source/texk/web2c/luatexdir/font/mapfile.c new file mode 100644 index 00000000000..5ea1e7ca0a2 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/font/mapfile.c @@ -0,0 +1,770 @@ +/* + +Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> +Copyright 2006-2010 Taco Hoekwater <taco@luatex.org> + +This file is part of LuaTeX. + +LuaTeX 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. + +LuaTeX 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU General Public License along +with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +*/ + +#include "ptexlib.h" +#include <math.h> +#include <kpathsea/c-auto.h> +#include <kpathsea/c-memstr.h> +#include <string.h> + +#define FM_BUF_SIZE 1024 + +static FILE *fm_file; + +static unsigned char *fm_buffer = NULL; +static int fm_size = 0; +static int fm_curbyte = 0; + +#define fm_open(a) (fm_file = fopen((char *)(a), FOPEN_RBIN_MODE)) +#define fm_read_file() readbinfile(fm_file,&fm_buffer,&fm_size) +#define fm_close() xfclose(fm_file, cur_file_name) +#define fm_getchar() fm_buffer[fm_curbyte++] +#define fm_eof() (fm_curbyte>fm_size) +#define is_cfg_comment(c) (c == 10 || c == '*' || c == '#' || c == ';' || c == '%') + +typedef enum { FM_DUPIGNORE, FM_REPLACE, FM_DELETE } updatemode; + +typedef struct mitem { + /*tex |FM_DUPIGNORE| or |FM_REPLACE| or |FM_DELETE| */ + updatemode mode; + /*tex map file or map line */ + maptype type; + /*tex pointer to map file name or map line */ + char *line; + /*tex line number in map file */ + int lineno; +} mapitem; + +mapitem *mitem = NULL; + +#define read_field(r, q, buf) do { \ + q = buf; \ + while (*r != ' ' && *r != '<' && *r != '"' && *r != '\0') \ + *q++ = *r++; \ + *q = '\0'; \ + skip_char(r, ' '); \ +} while (0) + +#define set_field(F) do { \ + if (q > buf) \ + fm->F = xstrdup(buf); \ + if (*r == '\0') \ + goto done; \ +} while (0) + +fm_entry *new_fm_entry(void) +{ + fm_entry *fm; + fm = xtalloc(1, fm_entry); + fm->tfm_name = NULL; + fm->ps_name = NULL; + fm->fd_flags = FD_FLAGS_NOT_SET_IN_MAPLINE; + fm->ff_name = NULL; + fm->encname = NULL; + fm->type = 0; + fm->slant = 0; + fm->extend = 1000; + unset_slantset(fm); + unset_extendset(fm); + unset_inuse(fm); + return fm; +} + +void delete_fm_entry(fm_entry * fm) +{ + xfree(fm->tfm_name); + xfree(fm->ps_name); + xfree(fm->ff_name); + xfree(fm); +} + +static ff_entry *new_ff_entry(void) +{ + ff_entry *ff; + ff = xtalloc(1, ff_entry); + ff->ff_name = NULL; + ff->ff_path = NULL; + return ff; +} + +static void delete_ff_entry(ff_entry * ff) +{ + xfree(ff->ff_name); + xfree(ff->ff_path); + xfree(ff); +} + +static struct avl_table *tfm_tree = NULL; +static struct avl_table *ff_tree = NULL; +static struct avl_table *encname_tree = NULL; + +/*tex + + We sort |fm_entry| into |tfm_tree| by |tfm_name|: + +*/ + +static int comp_fm_entry_tfm(const void *pa, const void *pb, void *p) +{ + (void) p; + return strcmp(((const fm_entry *) pa)->tfm_name, ((const fm_entry *) pb)->tfm_name); +} + +/* We sort |ff_entry| into |ff_tree| by |ff_name|: */ + +static int comp_ff_entry(const void *pa, const void *pb, void *p) +{ + (void) p; + return strcmp(((const ff_entry *) pa)->ff_name, ((const ff_entry *) pb)->ff_name); +} + +static void create_avl_trees(void) +{ + tfm_tree = avl_create(comp_fm_entry_tfm, NULL, &avl_xallocator); + ff_tree = avl_create(comp_ff_entry, NULL, &avl_xallocator); + encname_tree = avl_create(comp_string_entry, NULL, &avl_xallocator); +} + +int avl_do_entry(fm_entry * fm, int mode) +{ + fm_entry *p; + void *a; + void **aa; + int delete_new = 0; + if (tfm_tree == NULL) + create_avl_trees(); + p = (fm_entry *) avl_find(tfm_tree, fm); + if (p != NULL) { + switch (mode) { + case FM_DUPIGNORE: + formatted_warning("map file", "entry for '%s' already exists, duplicates ignored", fm->tfm_name); + delete_new = 1; + break; + case FM_REPLACE: + case FM_DELETE: + if (is_inuse(p)) { + formatted_warning("map file", "entry for '%s' has been used, replace/delete not allowed", fm->tfm_name); + delete_new = 1; + } else { + a = avl_delete(tfm_tree, p); + assert(a != NULL); + delete_fm_entry(p); + } + break; + default: + formatted_error("map file", "something bad happened",0); + } + } + if ((mode == FM_DUPIGNORE || mode == FM_REPLACE) && delete_new == 0) { + aa = avl_probe(tfm_tree, fm); + if (aa == NULL) { + /*tex Is this a problem? */ + } + } else + delete_new = 1; + return delete_new; +} + +/*tex + + Add the encoding name to an AVL tree. This has nothing to do with |writeenc.c|. + +*/ + +static char *add_encname(char *s) +{ + char *p; + void **aa; + if ((p = (char *) avl_find(encname_tree, s)) == NULL) { + /*tex The encoding name has not yet been registered. */ + p = xstrdup(s); + aa = avl_probe(encname_tree, p); + if (aa == NULL) { + /*tex Is this a problem? */ + } + } + return p; +} + +/*tex + + A consistency check for map entry, with warn flag. + +*/ + +static int check_fm_entry(fm_entry * fm, boolean warn) +{ + int a = 0; + if (is_fontfile(fm) && !is_included(fm)) { + if (warn) + formatted_warning("map file", + "ambiguous entry for '%s': font file present but not included, " + "will be treated as font file not present", fm->tfm_name); + xfree(fm->ff_name); + /*tex Do not set variable |a| as this entry will be still accepted. */ + } + /*tex If both ps_name and font file are missing, drop this entry. */ + if (fm->ps_name == NULL && !is_fontfile(fm)) { + if (warn) + formatted_warning("map file", "invalid entry for '%s': both ps_name and font file missing", fm->tfm_name); + a += 1; + } + /*tex \TRUETYPE\ fonts cannot be reencoded without subsetting. */ + if (is_truetype(fm) && is_reencoded(fm) && !is_subsetted(fm)) { + if (warn) + formatted_warning("map file", "invalid entry for '%s': only subsetted TrueType font can be reencoded", fm->tfm_name); + a += 2; + } + /*tex The value of |SlantFont| and |ExtendFont| must be reasonable. */ + if (fm->slant < FONT_SLANT_MIN || fm->slant > FONT_SLANT_MAX) { + if (warn) + formatted_warning("map file", "invalid entry for '%s': value '%g' is to large for SlantFont", + fm->tfm_name, fm->slant / 1000.0); + a += 8; + } + if (fm->extend < FONT_EXTEND_MIN || fm->extend > FONT_EXTEND_MAX) { + if (warn) + formatted_warning("map file", "invalid entry for '%s': value '%g' is too large for ExtendFont", + fm->tfm_name, fm->extend / 1000.0); + a += 16; + } + return a; +} + +/*tex + + Returns the font number if s is one of the 14 std. font names, -1 otherwise. + A bit speed trimmed. Using these base fonts is oldfashioned and doesn't + happen in a decent \LUATEX\ produced file. + +*/ + +int check_std_t1font(char *s) +{ + static const char *std_t1font_names[] = { + "Courier", /* 0:7 */ + "Courier-Bold", /* 1:12 */ + "Courier-Oblique", /* 2:15 */ + "Courier-BoldOblique", /* 3:19 */ + "Helvetica", /* 4:9 */ + "Helvetica-Bold", /* 5:14 */ + "Helvetica-Oblique", /* 6:17 */ + "Helvetica-BoldOblique", /* 7:21 */ + "Symbol", /* 8:6 */ + "Times-Roman", /* 9:11 */ + "Times-Bold", /* 10:10 */ + "Times-Italic", /* 11:12 */ + "Times-BoldItalic", /* 12:16 */ + "ZapfDingbats" /* 13:12 */ + }; + static const int index[] = { + -1, -1, -1, -1, -1, -1, 8, 0, -1, 4, 10, + 9, -1, -1, 5, 2, 12, 6, -1, 3, -1, 7 + }; + size_t n; + int k = -1; + n = strlen(s); + if (n > 21) + return -1; + if (n == 12) { + /*tex three names have length 12 */ + switch (*s) { + case 'C': + /*tex Courier-Bold */ + k = 1; + break; + case 'T': + /*tex Times-Italic */ + k = 11; + break; + case 'Z': + /*tex ZapfDingbats */ + k = 13; + break; + default: + return -1; + } + } else + k = index[n]; + if (k > -1 && !strcmp(std_t1font_names[k], s)) + return k; + return -1; +} + +static void fm_scan_line(void) +{ + int a, b, c, j, u = 0, v = 0; + char cc; + float d; + fm_entry *fm; + char fm_line[FM_BUF_SIZE], buf[FM_BUF_SIZE]; + char *p, *q, *s; + char *r = NULL; + switch (mitem->type) { + case MAPFILE: + p = fm_line; + while (!fm_eof()) { + if (fm_curbyte == fm_size) { + fm_curbyte++; + cc = 10; + } else { + cc = (char) fm_getchar(); + } + append_char_to_buf(cc, p, fm_line, FM_BUF_SIZE); + if (cc == 10) + break; + } + *(--p) = '\0'; + r = fm_line; + break; + case MAPLINE: + /*tex Work on a string from |makecstring|. */ + r = mitem->line; + break; + default: + assert(0); + } + if (*r == '\0' || is_cfg_comment(*r)) + return; + fm = new_fm_entry(); + read_field(r, q, buf); + set_field(tfm_name); + if (!isdigit((unsigned char)*r)) { + /*tex The 2nd field |ps_name| may not start with a digit. */ + read_field(r, q, buf); + set_field(ps_name); + } + if (isdigit((unsigned char)*r)) { + /*tex Is the font descriptor |/Flags| given? */ + for (s = r; isdigit((unsigned char)*s); s++); + if (*s == ' ' || *s == '"' || *s == '<' || *s == '\0') { + /*tex not e.g.\ |8r.enc| */ + fm->fd_flags = atoi(r); + while (isdigit((unsigned char)*r)) + r++; + } + } + /*tex Loop through specials, encoding, font file:*/ + while (1) { + skip_char(r, ' '); + switch (*r) { + case '\0': + goto done; + case '"': + /*tex The pening quote. */ + r++; + u = v = 0; + do { + skip_char(r, ' '); + if (sscanf(r, "%f %n", &d, &j) > 0) { + /*tex Jump behind number, eat also blanks, if any. */ + s = r + j; + if (*(s - 1) == 'E' || *(s - 1) == 'e') { + /*tex e.g.\ |0.5ExtendFont|: |%f = 0.5E| */ + s--; + } + if (str_prefix(s, "SlantFont")) { + /*tex Correct rounding also for negative numbers. */ + d *= (float) 1000.0; + fm->slant = (int) (d > 0 ? d + 0.5 : d - 0.5); + set_slantset(fm); + r = s + strlen("SlantFont"); + } else if (str_prefix(s, "ExtendFont")) { + d *= (float) 1000.0; + fm->extend = (int) (d > 0 ? d + 0.5 : d - 0.5); + set_extendset(fm); + r = s + strlen("ExtendFont"); + } else { + /*tex unknown name, jump over it */ + for (r = s; *r != ' ' && *r != '"' && *r != '\0'; r++); + c = *r; + *r = '\0'; + formatted_warning("map file", "invalid entry for '%s': unknown name '%s' ignored", fm->tfm_name, s); + *r = (char) c; + } + } else + for (; *r != ' ' && *r != '"' && *r != '\0'; r++); + } + while (*r == ' '); + if (*r == '"') { + /*tex The closing quote. */ + r++; + } else { + formatted_warning("map file", "invalid entry for '%s': closing quote missing", fm->tfm_name); + goto bad_line; + } + break; + case 'P': + /*tex Handle cases for sub fonts like |PidEid=3,1| */ + formatted_warning("map file", "invalid entry for '%s': subfonts are not supported", fm->tfm_name); + goto bad_line; + break; + default: + /*tex Encoding or font file specification. */ + a = b = 0; + if (*r == '<') { + a = *r++; + if (*r == '<' || *r == '[') + b = *r++; + } + read_field(r, q, buf); + /*tex Encoding, Formats: |8r.enc| or |<8r.enc| or |<[8r.enc| */ + if (strlen(buf) > 4 && strcasecmp(strend(buf) - 4, ".enc") == 0) { + /*tex |u|, |v| used if intervening blank: |<< foo| */ + fm->encname = add_encname(buf); + u = v = 0; + } else if (strlen(buf) > 0) { + /*tex + + We get the file name given where possible formats are: + + \starttabulate[|||] + \NC subsetting \NC \tpe {<cmr10.pfa} \NC \NR + \NC no subsetting \NC \tpe {<<cmr10.pfa} \NC \NR + \NC no embedding \NC \tpe {cmr10.pfa} \NC \NR + \stoptabulate + + */ + if (a == '<' || u == '<') { + set_included(fm); + if ((a == '<' && b == 0) || (a == 0 && v == 0)) { + set_subsetted(fm); + } else { + /*tex + + Otherwise |b| equals |<| or |[| which means that we have no subsetting. + */ + } + } + set_field(ff_name); + u = v = 0; + } else { + u = a; + v = b; + } + } + } + done: + if (fm->ps_name != NULL && (check_std_t1font(fm->ps_name) >= 0)) + set_std_t1font(fm); + if (is_fontfile(fm) && strlen(fm_fontfile(fm)) > 3) { + if (strcasecmp(strend(fm_fontfile(fm)) - 4, ".ttf") == 0) + set_truetype(fm); + else if (strcasecmp(strend(fm_fontfile(fm)) - 4, ".ttc") == 0) + set_truetype(fm); + else if (strcasecmp(strend(fm_fontfile(fm)) - 4, ".otf") == 0) + set_opentype(fm); + else + set_type1(fm); + } else { + /*tex Assume a builtin font is \TYPEONE\: */ + set_type1(fm); + } + if (check_fm_entry(fm, true) != 0) + goto bad_line; + /*tex + + Until here the map line has been completely scanned without errors; |fm| + points to a valid, freshly filled-out |fm_entry| structure. Now follows + the actual work of registering or deleting. + + */ + if (avl_do_entry(fm, mitem->mode) == 0) + return; + bad_line: + delete_fm_entry(fm); +} + +static void fm_read_info(void) +{ + int callback_id; + int file_opened = 0; + + if (tfm_tree == NULL) + create_avl_trees(); + if (mitem->line == NULL) { + /*tex There is nothing to do. */ + return; + } + mitem->lineno = 1; + switch (mitem->type) { + case MAPFILE: + xfree(fm_buffer); + fm_curbyte = 0; + fm_size = 0; + cur_file_name = luatex_find_file(mitem->line, find_map_file_callback); + if (cur_file_name) { + callback_id = callback_defined(read_map_file_callback); + if (callback_id > 0) { + if (run_callback(callback_id, "S->bSd", cur_file_name, + &file_opened, &fm_buffer, &fm_size)) { + if (file_opened) { + if (fm_size > 0) { + report_start_file(filetype_map,cur_file_name); + while (!fm_eof()) { + fm_scan_line(); + mitem->lineno++; + } + report_stop_file(filetype_map); + fm_file = NULL; + } + } else { + formatted_warning("map file", "cannot open font map file '%s'", cur_file_name); + } + } else { + formatted_warning("map file", "cannot open font map file '%s'", cur_file_name); + } + } else { + if (!fm_open(cur_file_name)) { + formatted_warning("map file", "cannot open font map file '%s'", cur_file_name); + } else { + fm_read_file(); + report_start_file(filetype_map,cur_file_name); + while (!fm_eof()) { + fm_scan_line(); + mitem->lineno++; + } + fm_close(); + report_stop_file(filetype_map); + fm_file = NULL; + } + } + cur_file_name = NULL; + } + break; + case MAPLINE: + cur_file_name = NULL; + fm_scan_line(); + break; + default: + assert(0); + } + /*tex Done with this line: */ + mitem->line = NULL; + cur_file_name = NULL; + return; +} + +fm_entry *getfontmap(char *tfm_name) +{ + fm_entry *fm; + fm_entry tmp; + if (tfm_name == NULL) { + /*tex Wide \LUA\ loaded fonts may not have a name. */ + return NULL; + } + if (tfm_tree == NULL) { + /*tex Only read the default map file. */ + fm_read_info(); + } + /*tex Look up the name. */ + tmp.tfm_name = tfm_name; + fm = (fm_entry *) avl_find(tfm_tree, &tmp); + if (fm == NULL) + return NULL; + set_inuse(fm); + return fm; +} + +/*tex + + Process map file given by its name or map line contents. Items not beginning + with [+-=] flush default map file, if it has not yet been read. Leading + blanks and blanks immediately following [+-=] are ignored. + +*/ + +void process_map_item(char *s, int type) +{ + char *p; + int mode; + if (*s == ' ') { + /*tex Ignore leading blanks: */ + s++; + } + switch (*s) { + case '+': + /* +mapfile.map, +mapline: insert an entry, if it is not duplicate */ + mode = FM_DUPIGNORE; + s++; + break; + case '=': + /* =mapfile.map, =mapline: try to replace an existing entry */ + mode = FM_REPLACE; + s++; + break; + case '-': + /* -mapfile.map, -mapline: try to delete an entry */ + mode = FM_DELETE; + s++; + break; + default: + /* like +, but also: flush the default map file name */ + mode = FM_DUPIGNORE; + mitem->line = NULL; + } + if (*s == ' ') { + /*tex Ignore a blank after |[+-=]| */ + s++; + } + /*tex The map item starts here. */ + p = s; + switch (type) { + case MAPFILE: + /*tex Remove blank at the end. */ + while (*p != '\0' && *p != ' ') + p++; + *p = '\0'; + break; + case MAPLINE: + /*tex A blank at end is allowed. */ + break; + default: + assert(0); + } + if (mitem->line != NULL) { + /*tex Read default map file first */ + fm_read_info(); + } + if (*s != '\0') { + /*tex Only if real item to process. */ + mitem->mode = mode; + mitem->type = type; + mitem->line = s; + fm_read_info(); + } +} + +void pdfmapfile(int t) +{ + char *s = tokenlist_to_cstring(t, true, NULL); + process_map_item(s, MAPFILE); + free(s); +} + +void pdfmapline(int t) +{ + char *s = tokenlist_to_cstring(t, true, NULL); + process_map_item(s, MAPLINE); + free(s); +} + +void pdf_init_map_file(const char *map_name) +{ + assert(mitem == NULL); + mitem = xtalloc(1, mapitem); + mitem->mode = FM_DUPIGNORE; + mitem->type = MAPFILE; + mitem->line = xstrdup(map_name); +} + +/*tex + + An early check whether a font file exists. Search tree |ff_tree| is used in + 1st instance, as it may be faster than the |kpse_find_file|, and + |kpse_find_file| is called only once per font file name plus expansion + parameter. This might help keeping speed, if many \PDF\ pages with same fonts + are to be embedded (not that we deal with that fragile approach any longer in + \LUATEX). + + The |ff_tree| contains only font files, which are actually needed, so this tree + typically is much smaller than the tfm_tree. + +*/ + +ff_entry *check_ff_exist(char *ff_name, boolean is_tt) +{ + ff_entry *ff; + ff_entry tmp; + void **aa; + int callback_id; + char *filepath = NULL; + tmp.ff_name = ff_name; + ff = (ff_entry *) avl_find(ff_tree, &tmp); + if (ff == NULL) { + /*tex The name is not yet in the database. */ + ff = new_ff_entry(); + ff->ff_name = xstrdup(ff_name); + if (is_tt) { + callback_id = callback_defined(find_truetype_file_callback); + if (callback_id > 0) { + run_callback(callback_id, "S->S", ff_name, &filepath); + if (filepath && strlen(filepath) == 0) + filepath = NULL; + ff->ff_path = filepath; + } else { + ff->ff_path = kpse_find_file(ff_name, kpse_truetype_format, 0); + } + } else { + callback_id = callback_defined(find_type1_file_callback); + if (callback_id > 0) { + run_callback(callback_id, "S->S", ff_name, &filepath); + if (filepath && strlen(filepath) == 0) + filepath = NULL; + ff->ff_path = filepath; + } else { + ff->ff_path = kpse_find_file(ff_name, kpse_type1_format, 0); + } + } + aa = avl_probe(ff_tree, ff); + if (aa == NULL) { + /*tex Is this a problem? */ + } + } + return ff; +} + +int is_subsetable(fm_entry * fm) +{ + assert(is_included(fm)); + return is_subsetted(fm); +} + +/*tex Cleaning up: */ + +static void destroy_fm_entry_tfm(void *pa, void *pb) +{ + fm_entry *fm; + (void) pb; + fm = (fm_entry *) pa; + delete_fm_entry(fm); +} + +static void destroy_ff_entry(void *pa, void *pb) +{ + ff_entry *ff; + (void) pb; + ff = (ff_entry *) pa; + delete_ff_entry(ff); +} + +void fm_free(void) +{ + if (tfm_tree != NULL) { + avl_destroy(tfm_tree, destroy_fm_entry_tfm); + tfm_tree = NULL; + } + if (ff_tree != NULL) { + avl_destroy(ff_tree, destroy_ff_entry); + ff_tree = NULL; + } +} diff --git a/Build/source/texk/web2c/luatexdir/font/mapfile.w b/Build/source/texk/web2c/luatexdir/font/mapfile.w deleted file mode 100644 index f47c5b50487..00000000000 --- a/Build/source/texk/web2c/luatexdir/font/mapfile.w +++ /dev/null @@ -1,715 +0,0 @@ -% mapfile.w -% -% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org> -% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org> -% -% This file is part of LuaTeX. -% -% LuaTeX 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. -% -% LuaTeX 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 Lesser General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License along -% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. - -@ @c - - -#include "ptexlib.h" -#include <math.h> -#include <kpathsea/c-auto.h> -#include <kpathsea/c-memstr.h> -#include <string.h> - -#define FM_BUF_SIZE 1024 - -static FILE *fm_file; - -static unsigned char *fm_buffer = NULL; -static int fm_size = 0; -static int fm_curbyte = 0; - -#define fm_open(a) (fm_file = fopen((char *)(a), FOPEN_RBIN_MODE)) -#define fm_read_file() readbinfile(fm_file,&fm_buffer,&fm_size) -#define fm_close() xfclose(fm_file, cur_file_name) -#define fm_getchar() fm_buffer[fm_curbyte++] -#define fm_eof() (fm_curbyte>fm_size) -#define is_cfg_comment(c) \ - (c == 10 || c == '*' || c == '#' || c == ';' || c == '%') - -typedef enum { FM_DUPIGNORE, FM_REPLACE, FM_DELETE } updatemode; - -typedef struct mitem { - updatemode mode; /* FM_DUPIGNORE or FM_REPLACE or FM_DELETE */ - maptype type; /* map file or map line */ - char *line; /* pointer to map file name or map line */ - int lineno; /* line number in map file */ -} mapitem; -mapitem *mitem = NULL; - -#define read_field(r, q, buf) do { \ - q = buf; \ - while (*r != ' ' && *r != '<' && *r != '"' && *r != '\0') \ - *q++ = *r++; \ - *q = '\0'; \ - skip_char(r, ' '); \ -} while (0) - -#define set_field(F) do { \ - if (q > buf) \ - fm->F = xstrdup(buf); \ - if (*r == '\0') \ - goto done; \ -} while (0) - -fm_entry *new_fm_entry(void) -{ - fm_entry *fm; - fm = xtalloc(1, fm_entry); - fm->tfm_name = NULL; - fm->ps_name = NULL; - fm->fd_flags = FD_FLAGS_NOT_SET_IN_MAPLINE; - fm->ff_name = NULL; - fm->encname = NULL; - fm->type = 0; - fm->slant = 0; - fm->extend = 1000; - unset_slantset(fm); - unset_extendset(fm); - unset_inuse(fm); - return fm; -} - -void delete_fm_entry(fm_entry * fm) -{ - xfree(fm->tfm_name); - xfree(fm->ps_name); - xfree(fm->ff_name); - xfree(fm); -} - -static ff_entry *new_ff_entry(void) -{ - ff_entry *ff; - ff = xtalloc(1, ff_entry); - ff->ff_name = NULL; - ff->ff_path = NULL; - return ff; -} - -static void delete_ff_entry(ff_entry * ff) -{ - xfree(ff->ff_name); - xfree(ff->ff_path); - xfree(ff); -} - -/**********************************************************************/ - -static struct avl_table *tfm_tree = NULL; -static struct avl_table *ff_tree = NULL; -static struct avl_table *encname_tree = NULL; - -/* AVL sort fm_entry into tfm_tree by tfm_name */ - -static int comp_fm_entry_tfm(const void *pa, const void *pb, void *p) -{ - (void) p; - return strcmp(((const fm_entry *) pa)->tfm_name, - ((const fm_entry *) pb)->tfm_name); -} - -/* AVL sort ff_entry into ff_tree by ff_name */ - -static int comp_ff_entry(const void *pa, const void *pb, void *p) -{ - (void) p; - return strcmp(((const ff_entry *) pa)->ff_name, - ((const ff_entry *) pb)->ff_name); -} - -static void create_avl_trees(void) -{ - assert(tfm_tree == NULL); - tfm_tree = avl_create(comp_fm_entry_tfm, NULL, &avl_xallocator); - assert(tfm_tree != NULL); - assert(ff_tree == NULL); - ff_tree = avl_create(comp_ff_entry, NULL, &avl_xallocator); - assert(ff_tree != NULL); - assert(encname_tree == NULL); - encname_tree = avl_create(comp_string_entry, NULL, &avl_xallocator); - assert(encname_tree != NULL); -} - -int avl_do_entry(fm_entry * fm, int mode) -{ - fm_entry *p; - void *a; - void **aa; - int delete_new = 0; - if (tfm_tree == NULL) - create_avl_trees(); - p = (fm_entry *) avl_find(tfm_tree, fm); - if (p != NULL) { - switch (mode) { - case FM_DUPIGNORE: - formatted_warning("map file", "entry for '%s' already exists, duplicates ignored", fm->tfm_name); - delete_new = 1; - break; - case FM_REPLACE: - case FM_DELETE: - if (is_inuse(p)) { - formatted_warning("map file", "entry for '%s' has been used, replace/delete not allowed", fm->tfm_name); - delete_new = 1; - } else { - a = avl_delete(tfm_tree, p); - assert(a != NULL); - delete_fm_entry(p); - } - break; - default: - assert(0); - } - } - if ((mode == FM_DUPIGNORE || mode == FM_REPLACE) && delete_new == 0) { - aa = avl_probe(tfm_tree, fm); - assert(aa != NULL); - } else - delete_new = 1; - return delete_new; -} - -/* add the encoding name to an AVL tree. this has nothing to do with writeenc.c */ - -static char *add_encname(char *s) -{ - char *p; - void **aa; - assert(s != NULL); - assert(encname_tree != NULL); - if ((p = (char *) avl_find(encname_tree, s)) == NULL) { /* encoding name not yet registered */ - p = xstrdup(s); - aa = avl_probe(encname_tree, p); - assert(aa != NULL); - } - return p; -} - -/**********************************************************************/ -/* consistency check for map entry, with warn flag */ - -static int check_fm_entry(fm_entry * fm, boolean warn) -{ - int a = 0; - assert(fm != NULL); - - if (is_fontfile(fm) && !is_included(fm)) { - if (warn) - formatted_warning("map file", - "ambiguous entry for '%s': font file present but not included, " - "will be treated as font file not present", fm->tfm_name); - xfree(fm->ff_name); - /* do not set variable |a| as this entry will be still accepted */ - } - - /* if both ps_name and font file are missing, drop this entry */ - if (fm->ps_name == NULL && !is_fontfile(fm)) { - if (warn) - formatted_warning("map file", "invalid entry for '%s': both ps_name and font file missing", fm->tfm_name); - a += 1; - } - - /* TrueType fonts cannot be reencoded without subsetting */ - if (is_truetype(fm) && is_reencoded(fm) && !is_subsetted(fm)) { - if (warn) - formatted_warning("map file", "invalid entry for '%s': only subsetted TrueType font can be reencoded", fm->tfm_name); - a += 2; - } - - /* the value of SlantFont and ExtendFont must be reasonable */ - if (fm->slant < FONT_SLANT_MIN || fm->slant > FONT_SLANT_MAX) { - if (warn) - formatted_warning("map file", "invalid entry for '%s': value '%g' is to large for SlantFont", - fm->tfm_name, fm->slant / 1000.0); - a += 8; - } - if (fm->extend < FONT_EXTEND_MIN || fm->extend > FONT_EXTEND_MAX) { - if (warn) - formatted_warning("map file", "invalid entry for '%s': value '%g' is too large for ExtendFont", - fm->tfm_name, fm->extend / 1000.0); - a += 16; - } - - return a; -} - -/**********************************************************************/ -/* returns the font number if s is one of the 14 std. font names, -1 otherwise; speed-trimmed. */ - -int check_std_t1font(char *s) -{ - static const char *std_t1font_names[] = { - "Courier", /* 0:7 */ - "Courier-Bold", /* 1:12 */ - "Courier-Oblique", /* 2:15 */ - "Courier-BoldOblique", /* 3:19 */ - "Helvetica", /* 4:9 */ - "Helvetica-Bold", /* 5:14 */ - "Helvetica-Oblique", /* 6:17 */ - "Helvetica-BoldOblique", /* 7:21 */ - "Symbol", /* 8:6 */ - "Times-Roman", /* 9:11 */ - "Times-Bold", /* 10:10 */ - "Times-Italic", /* 11:12 */ - "Times-BoldItalic", /* 12:16 */ - "ZapfDingbats" /* 13:12 */ - }; - static const int index[] = - { -1, -1, -1, -1, -1, -1, 8, 0, -1, 4, 10, 9, -1, -1, 5, 2, 12, 6, -1, - 3, -1, 7 - }; - size_t n; - int k = -1; - assert(s != NULL); - n = strlen(s); - if (n > 21) - return -1; - if (n == 12) { /* three names have length 12 */ - switch (*s) { - case 'C': - k = 1; /* Courier-Bold */ - break; - case 'T': - k = 11; /* Times-Italic */ - break; - case 'Z': - k = 13; /* ZapfDingbats */ - break; - default: - return -1; - } - } else - k = index[n]; - if (k > -1 && !strcmp(std_t1font_names[k], s)) - return k; - return -1; -} - -/**********************************************************************/ - -static void fm_scan_line(void) -{ - int a, b, c, j, u = 0, v = 0; - char cc; - float d; - fm_entry *fm; - char fm_line[FM_BUF_SIZE], buf[FM_BUF_SIZE]; - char *p, *q, *s; - char *r = NULL; - switch (mitem->type) { - case MAPFILE: - p = fm_line; - while (!fm_eof()) { - if (fm_curbyte == fm_size) { - fm_curbyte++; - cc = 10; - } else { - cc = (char) fm_getchar(); - } - append_char_to_buf(cc, p, fm_line, FM_BUF_SIZE); - if (cc == 10) - break; - } - *(--p) = '\0'; - r = fm_line; - break; - case MAPLINE: - r = mitem->line; /* work on string from makecstring() */ - break; - default: - assert(0); - } - if (*r == '\0' || is_cfg_comment(*r)) - return; - fm = new_fm_entry(); - read_field(r, q, buf); - set_field(tfm_name); - if (!isdigit((unsigned char)*r)) { /* 2nd field ps_name may not start with a digit */ - read_field(r, q, buf); - set_field(ps_name); - } - if (isdigit((unsigned char)*r)) { /* font descriptor /Flags given? */ - for (s = r; isdigit((unsigned char)*s); s++); - if (*s == ' ' || *s == '"' || *s == '<' || *s == '\0') { /* not e. g. 8r.enc */ - fm->fd_flags = atoi(r); - while (isdigit((unsigned char)*r)) - r++; - } - } - while (1) { /* loop through "specials", encoding, font file */ - skip_char(r, ' '); - switch (*r) { - case '\0': - goto done; - case '"': /* opening quote */ - r++; - u = v = 0; - do { - skip_char(r, ' '); - if (sscanf(r, "%f %n", &d, &j) > 0) { - s = r + j; /* jump behind number, eat also blanks, if any */ - if (*(s - 1) == 'E' || *(s - 1) == 'e') - s--; /* e. g. 0.5ExtendFont: %f = 0.5E */ - if (str_prefix(s, "SlantFont")) { - d *= (float) 1000.0; /* correct rounding also for neg. numbers */ - fm->slant = (int) (d > 0 ? d + 0.5 : d - 0.5); - set_slantset(fm); - r = s + strlen("SlantFont"); - } else if (str_prefix(s, "ExtendFont")) { - d *= (float) 1000.0; - fm->extend = (int) (d > 0 ? d + 0.5 : d - 0.5); - set_extendset(fm); - r = s + strlen("ExtendFont"); - } else { /* unknown name */ - for (r = s; *r != ' ' && *r != '"' && *r != '\0'; r++); /* jump over name */ - c = *r; /* remember char for temporary end of string */ - *r = '\0'; - formatted_warning("map file", "invalid entry for '%s': unknown name '%s' ignored", fm->tfm_name, s); - *r = (char) c; - } - } else - for (; *r != ' ' && *r != '"' && *r != '\0'; r++); - } - while (*r == ' '); - if (*r == '"') /* closing quote */ - r++; - else { - formatted_warning("map file", "invalid entry for '%s': closing quote missing", fm->tfm_name); - goto bad_line; - } - break; - case 'P': /* handle cases for sub fonts like 'PidEid=3,1' */ - formatted_warning("map file", "invalid entry for '%s': subfonts are not supported", fm->tfm_name); - goto bad_line; - break; - default: /* encoding or font file specification */ - a = b = 0; - if (*r == '<') { - a = *r++; - if (*r == '<' || *r == '[') - b = *r++; - } - read_field(r, q, buf); - /* encoding, formats: '8r.enc' or '<8r.enc' or '<[8r.enc' */ - if (strlen(buf) > 4 && strcasecmp(strend(buf) - 4, ".enc") == 0) { - fm->encname = add_encname(buf); - u = v = 0; /* u, v used if intervening blank: "<< foo" */ - } else if (strlen(buf) > 0) { /* file name given */ - /* font file, formats: - * subsetting: '<cmr10.pfa' - * no subsetting: '<<cmr10.pfa' - * no embedding: 'cmr10.pfa' - */ - if (a == '<' || u == '<') { - set_included(fm); - if ((a == '<' && b == 0) || (a == 0 && v == 0)) - set_subsetted(fm); - /* otherwise b == '<' (or '[') => no subsetting */ - } - set_field(ff_name); - u = v = 0; - } else { - u = a; - v = b; - } - } - } - done: - if (fm->ps_name != NULL && (check_std_t1font(fm->ps_name) >= 0)) - set_std_t1font(fm); - if (is_fontfile(fm) && strlen(fm_fontfile(fm)) > 3) { - if (strcasecmp(strend(fm_fontfile(fm)) - 4, ".ttf") == 0) - set_truetype(fm); - else if (strcasecmp(strend(fm_fontfile(fm)) - 4, ".ttc") == 0) - set_truetype(fm); - else if (strcasecmp(strend(fm_fontfile(fm)) - 4, ".otf") == 0) - set_opentype(fm); - else - set_type1(fm); - } else - set_type1(fm); /* assume a builtin font is Type1 */ - if (check_fm_entry(fm, true) != 0) - goto bad_line; - /* - Until here the map line has been completely scanned without errors; - fm points to a valid, freshly filled-out fm_entry structure. - Now follows the actual work of registering/deleting. - */ - if (avl_do_entry(fm, mitem->mode) == 0) - return; - bad_line: - delete_fm_entry(fm); -} - -/**********************************************************************/ - -static void fm_read_info(void) -{ - int callback_id; - int file_opened = 0; - - if (tfm_tree == NULL) - create_avl_trees(); - if (mitem->line == NULL) /* nothing to do */ - return; - mitem->lineno = 1; - switch (mitem->type) { - case MAPFILE: - xfree(fm_buffer); - fm_curbyte = 0; - fm_size = 0; - cur_file_name = luatex_find_file(mitem->line, find_map_file_callback); - if (cur_file_name) { - callback_id = callback_defined(read_map_file_callback); - if (callback_id > 0) { - if (run_callback(callback_id, "S->bSd", cur_file_name, - &file_opened, &fm_buffer, &fm_size)) { - if (file_opened) { - if (fm_size > 0) { - report_start_file(filetype_map,cur_file_name); - while (!fm_eof()) { - fm_scan_line(); - mitem->lineno++; - } - report_stop_file(filetype_map); - fm_file = NULL; - } - } else { - formatted_warning("map file", "cannot open font map file '%s'", cur_file_name); - } - } else { - formatted_warning("map file", "cannot open font map file '%s'", cur_file_name); - } - } else { - if (!fm_open(cur_file_name)) { - formatted_warning("map file", "cannot open font map file '%s'", cur_file_name); - } else { - fm_read_file(); - report_start_file(filetype_map,cur_file_name); - while (!fm_eof()) { - fm_scan_line(); - mitem->lineno++; - } - fm_close(); - report_stop_file(filetype_map); - fm_file = NULL; - } - } - cur_file_name = NULL; - } - break; - case MAPLINE: - cur_file_name = NULL; - fm_scan_line(); - break; - default: - assert(0); - } - mitem->line = NULL; /* done with this line */ - cur_file_name = NULL; - return; -} - -/**********************************************************************/ - -fm_entry *getfontmap(char *tfm_name) -{ - fm_entry *fm; - fm_entry tmp; - if (tfm_name == NULL) /* wide, lua loaded fonts may not have a name */ - return NULL; - if (tfm_tree == NULL) - fm_read_info(); /* only to read default map file */ - tmp.tfm_name = tfm_name; /* Look up for tfmname */ - fm = (fm_entry *) avl_find(tfm_tree, &tmp); - if (fm == NULL) - return NULL; - set_inuse(fm); - return fm; -} - -/**********************************************************************/ -/* - * Process map file given by its name or map line contents. Items not - * beginning with [+-=] flush default map file, if it has not yet been - * read. Leading blanks and blanks immediately following [+-=] are - * ignored. - */ - -void process_map_item(char *s, int type) -{ - char *p; - int mode; - if (*s == ' ') - s++; /* ignore leading blank */ - switch (*s) { - case '+': /* +mapfile.map, +mapline */ - mode = FM_DUPIGNORE; /* insert entry, if it is not duplicate */ - s++; - break; - case '=': /* =mapfile.map, =mapline */ - mode = FM_REPLACE; /* try to replace earlier entry */ - s++; - break; - case '-': /* -mapfile.map, -mapline */ - mode = FM_DELETE; /* try to delete entry */ - s++; - break; - default: - mode = FM_DUPIGNORE; /* like +, but also: */ - mitem->line = NULL; /* flush default map file name */ - } - if (*s == ' ') - s++; /* ignore blank after [+-=] */ - p = s; /* map item starts here */ - switch (type) { - case MAPFILE: /* remove blank at end */ - while (*p != '\0' && *p != ' ') - p++; - *p = '\0'; - break; - case MAPLINE: /* blank at end allowed */ - break; - default: - assert(0); - } - if (mitem->line != NULL) /* read default map file first */ - fm_read_info(); - if (*s != '\0') { /* only if real item to process */ - mitem->mode = mode; - mitem->type = type; - mitem->line = s; - fm_read_info(); - } -} - -void pdfmapfile(int t) -{ - char *s = tokenlist_to_cstring(t, true, NULL); - process_map_item(s, MAPFILE); - free(s); -} - -void pdfmapline(int t) -{ - char *s = tokenlist_to_cstring(t, true, NULL); - process_map_item(s, MAPLINE); - free(s); -} - -void pdf_init_map_file(const char *map_name) -{ - assert(mitem == NULL); - mitem = xtalloc(1, mapitem); - mitem->mode = FM_DUPIGNORE; - mitem->type = MAPFILE; - mitem->line = xstrdup(map_name); -} - -/**********************************************************************/ -/* - * Early check whether a font file exists. Search tree ff_tree is used - * in 1st instance, as it may be faster than the kpse_find_file(), and - * kpse_find_file() is called only once per font file name + expansion - * parameter. This might help keeping speed, if many PDF pages with - * same fonts are to be embedded. - * - * The ff_tree contains only font files, which are actually needed, - * so this tree typically is much smaller than the tfm_tree. - */ - -ff_entry *check_ff_exist(char *ff_name, boolean is_tt) -{ - ff_entry *ff; - ff_entry tmp; - void **aa; - int callback_id; - char *filepath = NULL; - - assert(ff_name != NULL); - tmp.ff_name = ff_name; - ff = (ff_entry *) avl_find(ff_tree, &tmp); - if (ff == NULL) { /* not yet in database */ - ff = new_ff_entry(); - ff->ff_name = xstrdup(ff_name); - if (is_tt) { - callback_id = callback_defined(find_truetype_file_callback); - if (callback_id > 0) { - run_callback(callback_id, "S->S", ff_name, &filepath); - if (filepath && strlen(filepath) == 0) - filepath = NULL; - ff->ff_path = filepath; - } else { - ff->ff_path = kpse_find_file(ff_name, kpse_truetype_format, 0); - } - } else { - callback_id = callback_defined(find_type1_file_callback); - if (callback_id > 0) { - run_callback(callback_id, "S->S", ff_name, &filepath); - if (filepath && strlen(filepath) == 0) - filepath = NULL; - ff->ff_path = filepath; - } else { - ff->ff_path = kpse_find_file(ff_name, kpse_type1_format, 0); - } - } - aa = avl_probe(ff_tree, ff); - assert(aa != NULL); - } - return ff; -} - -/**********************************************************************/ - -int is_subsetable(fm_entry * fm) -{ - assert(is_included(fm)); - return is_subsetted(fm); -} - -/**********************************************************************/ -/* cleaning up... */ - -static void destroy_fm_entry_tfm(void *pa, void *pb) -{ - fm_entry *fm; - (void) pb; - fm = (fm_entry *) pa; - delete_fm_entry(fm); -} - -static void destroy_ff_entry(void *pa, void *pb) -{ - ff_entry *ff; - (void) pb; - ff = (ff_entry *) pa; - delete_ff_entry(ff); -} - -void fm_free(void) -{ - if (tfm_tree != NULL) { - avl_destroy(tfm_tree, destroy_fm_entry_tfm); - tfm_tree = NULL; - } - if (ff_tree != NULL) { - avl_destroy(ff_tree, destroy_ff_entry); - ff_tree = NULL; - } -} diff --git a/Build/source/texk/web2c/luatexdir/font/pkin.w b/Build/source/texk/web2c/luatexdir/font/pkin.c index a5d3eb4bccb..afebdef33e4 100644 --- a/Build/source/texk/web2c/luatexdir/font/pkin.w +++ b/Build/source/texk/web2c/luatexdir/font/pkin.c @@ -1,63 +1,56 @@ -% pkin.w -% -% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org> -% Copyright 2006-2008 Taco Hoekwater <taco@@luatex.org> -% -% This file is part of LuaTeX. -% -% LuaTeX 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. -% -% LuaTeX 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 Lesser General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License along -% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +/* -@ -NAME +Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> +Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> -pkin.c - implementation of readchar() +This file is part of LuaTeX. -DESCRIPTION +LuaTeX 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 implementation of readchar() uses parts of the program dvips -written by Tomas Rokicki--the inventor of the pkformat--(loadfont.c, -download.c and unpack.c). Dvips in turn is derived from pktype. -Pktype(TeX) is described in debt in ``The PKtype processor'', -which is available as pktype.weave as part of the METAFONTware. -What was needed to implement readchar() is rearranged in pkfile.c to -get more modularity in the style of MODULA2. +LuaTeX 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 Lesser General Public +License for more details. -BUGFIXES +You should have received a copy of the GNU General Public License along +with LuaTeX; if not, see <http://www.gnu.org/licenses/>. -May 1997: Eric Delaunay <delaunay@@lix.polytechnique.fr> reports a -problem with huge fonts (greater than 1008 DPI). The code for -handling PK characters in `extended format' was wrongly derived -from dvips. Made some minor improvements regarding error handling. +*/ -REDESIGN +/*tex -Piet Tutelaers <rcpt@@urc.tue.nl> +This implementation of readchar() uses parts of the program dvips written by +Tomas Rokicki--the inventor of the pkformat--(loadfont.c, download.c and +unpack.c). Dvips in turn is derived from pktype. Pktype(TeX) is described in debt +in ``The PKtype processor'', which is available as pktype.weave as part of the +METAFONTware. What was needed to implement readchar() is rearranged in pkfile.c +to get more modularity in the style of MODULA2. -Modified for use with pdftex by Han The Thanh <thanh@@fi.muni.cz>. +May 1997: Eric Delaunay <delaunay@lix.polytechnique.fr> reports a problem with +huge fonts (greater than 1008 DPI). The code for handling PK characters in +`extended format' was wrongly derived from dvips. Made some minor improvements +regarding error handling. -@c +At some point Piet Tutelaers <rcpt@urc.tue.nl> redesigned the code and later Han +The Thanh <thanh@fi.muni.cz> again modified the code to suite \PDFTEX. Of course +in \LUATEX\ again we adapted the code. +*/ #include "ptexlib.h" typedef short shalfword; -@ -Now we have some routines to get stuff from the pk file. pkbyte returns -the next byte from the pk file. +/*tex + +Now we have some routines to get stuff from the \PK\ file. |pkbyte| returns the +next byte from the \PK\ file. + +*/ -@c static shalfword pkbyte(void) { register shalfword i; @@ -70,7 +63,6 @@ static shalfword pkbyte(void) static int pkduo(void) { register int i; - i = pkbyte(); if (i > 127) i -= 256; @@ -81,7 +73,6 @@ static int pkduo(void) static int pktrio(void) { register int i; - i = pkbyte(); if (i > 127) i -= 256; @@ -93,7 +84,6 @@ static int pktrio(void) static int pkquad(void) { register int i; - i = pkbyte(); if (i > 127) i -= 256; @@ -103,14 +93,13 @@ static int pkquad(void) return (i); } +/*tex + The next part is devoted to unpacking the character data. We need procedures + to get a nybble, bit, and packed word from the packed data structure. -@ The next part is devoted to unpacking the character data. - -@ We need procedures to get a nybble, bit, and packed word from the -packed data structure. +*/ -@c static halfword inputbyte, flagbyte; static halfword bitweight; static halfword dynf; @@ -154,10 +143,10 @@ static halfword pkpackednum(void) i++; } while (!(j != 0)); if (i > 3) { -/* - Damn, we got a huge count! We {\it fake} it by giving an artificially - large repeat count. - */ + /*tex + Hm, we got a huge count! We {\em fake} it by giving an + artificially large repeat count. + */ return (handlehuge(i, j)); } else { while (i > 0) { @@ -175,9 +164,6 @@ static halfword pkpackednum(void) repeatcount = pkpackednum(); else repeatcount = 1; -#ifdef DEBUG - printf("[%d]", (int) repeatcount); -#endif return ((*realfunc) ()); } } @@ -185,7 +171,6 @@ static halfword pkpackednum(void) static halfword rest(void) { halfword i; - if (pk_remainder < 0) { pk_remainder = -pk_remainder; return (0); @@ -202,13 +187,12 @@ static halfword rest(void) } else { normal_error("type 3","pk issue that shouldn't happen"); return 0; - /*NOTREACHED*/} + } } static halfword handlehuge(halfword i, halfword k) { register long j = k; - while (i) { j = (j << 4L) + getnyb(); i--; @@ -219,11 +203,16 @@ static halfword handlehuge(halfword i, halfword k) } -@ And now we have our unpacking routine. +/*tex + + And now we have our unpacking routine. + +*/ -@c -static halfword gpower[17] = { 0, 1, 3, 7, 15, 31, 63, 127, - 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535 +static halfword gpower[17] = { + 0, 1, 3, 7, 15, 31, 63, 127, + 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, + 65535 }; static void unpack(chardesc * cd) @@ -236,7 +225,6 @@ static void unpack(chardesc * cd) shalfword hbit; halfword count; shalfword wordwidth; - wordwidth = (shalfword) ((cd->cwidth + 15) / 16); i = (int) (2 * cd->cheight * (long) wordwidth); if (i <= 0) @@ -317,80 +305,89 @@ static void unpack(chardesc * cd) } } -@ -|readchar()|: the main routine -check pk preamble if necessary, -Reads the character definition of character `c' into `cd' if available, -return FALSE (0) otherwise. +/*tex + + The main routine check pk preamble if necessary. It reads the character + definition of character |c| into |cd| if available or return |FALSE| + otherwise. + +*/ -@c int readchar(boolean check_preamble, chardesc * cd) { register shalfword i; register int k; register int length = 0; - -/* - Check the preamble of the pkfile - */ + /*tex Check the preamble of the \PK\ file. */ if (check_preamble) { if (pkbyte() != 247) normal_error("type 3","bad pk file, expected pre"); if (pkbyte() != 89) normal_error("type 3","bad version of pk file"); - for (i = pkbyte(); i > 0; i--) /* creator of pkfile */ + /*tex The creator of the file: */ + for (i = pkbyte(); i > 0; i--) (void) pkbyte(); - (void) pkquad(); /* design size */ - k = pkquad(); /* checksum */ - k = pkquad(); /* hppp */ - k = pkquad(); /* vppp */ + /*tex The design size: */ + (void) pkquad(); + /*tex The checksum: */ + k = pkquad(); + /*tex The hppp: */ + k = pkquad(); + /*tex The vppp: */ + k = pkquad(); } -/* - Now we skip to the desired character definition - */ + /*tex + We also skip to the desired character definition. + */ while ((flagbyte = pkbyte()) != 245) { if (flagbyte < 240) { switch (flagbyte & 7) { - case 0: - case 1: - case 2: - case 3: - length = (flagbyte & 7) * 256 + pkbyte() - 3; - cd->charcode = pkbyte(); - (void) pktrio(); /* TFMwidth */ - cd->xescape = pkbyte(); /* pixel width */ - cd->cwidth = pkbyte(); - cd->cheight = pkbyte(); - cd->xoff = pkbyte(); - cd->yoff = pkbyte(); - if (cd->xoff > 127) - cd->xoff -= 256; - if (cd->yoff > 127) - cd->yoff -= 256; - break; - case 4: - case 5: - case 6: - length = (int) ((flagbyte & 3) * 65536L + pkbyte() * 256L); - length = (int) (length + pkbyte() - 4L); - cd->charcode = pkbyte(); - (void) pktrio(); /* TFMwidth */ - cd->xescape = pkduo(); /* pixelwidth */ - cd->cwidth = pkduo(); - cd->cheight = pkduo(); - cd->xoff = pkduo(); - cd->yoff = pkduo(); - break; - case 7: - length = (int) (pkquad() - 9L); - cd->charcode = pkquad(); - (void) pkquad(); /* TFMwidth */ - cd->xescape = pkquad(); /* pixelwidth */ - k = pkquad(); - cd->cwidth = pkquad(); - cd->cheight = pkquad(); - cd->xoff = pkquad(); - cd->yoff = pkquad(); + case 0: + case 1: + case 2: + case 3: + length = (flagbyte & 7) * 256 + pkbyte() - 3; + cd->charcode = pkbyte(); + /*tex The \TFM\ width: */ + (void) pktrio(); + /*tex the pixel width: */ + cd->xescape = pkbyte(); + cd->cwidth = pkbyte(); + cd->cheight = pkbyte(); + cd->xoff = pkbyte(); + cd->yoff = pkbyte(); + if (cd->xoff > 127) + cd->xoff -= 256; + if (cd->yoff > 127) + cd->yoff -= 256; + break; + case 4: + case 5: + case 6: + length = (int) ((flagbyte & 3) * 65536L + pkbyte() * 256L); + length = (int) (length + pkbyte() - 4L); + cd->charcode = pkbyte(); + /*tex The \TFM\ width: */ + (void) pktrio(); + /*tex the pixel width: */ + cd->xescape = pkduo(); + cd->cwidth = pkduo(); + cd->cheight = pkduo(); + cd->xoff = pkduo(); + cd->yoff = pkduo(); + break; + case 7: + length = (int) (pkquad() - 9L); + cd->charcode = pkquad(); + /*tex The \TFM\ width: */ + (void) pkquad(); + /*tex the pixel width: */ + cd->xescape = pkquad(); + k = pkquad(); + cd->cwidth = pkquad(); + cd->cheight = pkquad(); + cd->xoff = pkquad(); + cd->yoff = pkquad(); } if (length <= 0) formatted_error("type 3","pk packet length '%i' too small", (int) length); @@ -399,28 +396,29 @@ int readchar(boolean check_preamble, chardesc * cd) } else { k = 0; switch (flagbyte) { - case 243: - k = pkbyte(); - if (k > 127) - k -= 256; - case 242: - k = k * 256 + pkbyte(); - case 241: - k = k * 256 + pkbyte(); - case 240: - k = k * 256 + pkbyte(); - while (k-- > 0) - i = pkbyte(); - break; - case 244: - k = pkquad(); - break; - case 246: - break; - default: - formatted_error("type 3","unexpected pk command '%i'", (int) flagbyte); + case 243: + k = pkbyte(); + if (k > 127) + k -= 256; + case 242: + k = k * 256 + pkbyte(); + case 241: + k = k * 256 + pkbyte(); + case 240: + k = k * 256 + pkbyte(); + while (k-- > 0) + i = pkbyte(); + break; + case 244: + k = pkquad(); + break; + case 246: + break; + default: + formatted_error("type 3","unexpected pk command '%i'", (int) flagbyte); } } } - return 0; /* character not found */ + /*tex Character not found: */ + return 0; } diff --git a/Build/source/texk/web2c/luatexdir/font/sfnt.w b/Build/source/texk/web2c/luatexdir/font/sfnt.c index 83e38990dd9..c7f4723c407 100644 --- a/Build/source/texk/web2c/luatexdir/font/sfnt.w +++ b/Build/source/texk/web2c/luatexdir/font/sfnt.c @@ -1,53 +1,58 @@ -% sfnt.w -% -% Copyright 2002 by Jin-Hwan Cho and Shunsaku Hirata, -% the dvipdfmx project team <dvipdfmx@@project.ktug.or.kr> -% Copyright 2006-2008 Taco Hoekwater <taco@@luatex.org> -% -% This file is part of LuaTeX. -% -% LuaTeX 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. -% -% LuaTeX 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 Lesser General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License along -% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. - -@ Based on dvipdfmx-0.13.2c -@c +/* +Copyright 2002 by Jin-Hwan Cho and Shunsaku Hirata, +the dvipdfmx project team <dvipdfmx@@project.ktug.or.kr> +Copyright 2006-2008 Taco Hoekwater <taco@@luatex.org> + +This file is part of LuaTeX. + +LuaTeX 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. + +LuaTeX 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU General Public License along +with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +*/ + +/*tex + + The code below is originally based on |dvipdfmx-0.13.2c|: + +*/ #include "ptexlib.h" -#if HAVE_CONFIG_H +#if HAVE_CONFIG_H # include <w2c/config.h> -#endif /* |HAVE_CONFIG_H_| */ +#endif #include <string.h> #include "font/sfnt.h" -@ type: - - `true' (0x74727565): TrueType (Mac) - - `typ1' (0x74797031) (Mac): PostScript font housed in a sfnt wrapper +/*tex - 0x00010000: TrueType (Win)/OpenType + Types: - `OTTO': PostScript CFF font with OpenType wrapper + \starttabulate[||||] + \NC \type {true} \NC 0x74727565 \NC (Mac) TrueType \NC \NR + \NC \type {typ1| \NC 0x74797031 \NC (Mac) PostScript font housed in a sfnt wrapper \NC \NR + \NC \NC 0x00010000 \NC TrueType (Win)/OpenType \NC \NR + \NC \type {OTTO} \NC \NC PostScript CFF font with OpenType wrapper \NC \NR + \NC \type {ttcf} \NC \NC TrueType Collection \NC \NR + \stoptabulate - `ttcf': TrueType Collection +*/ -@c #define SFNT_TRUETYPE 0x00010000UL -#define SFNT_MAC_TRUE 0x74727565UL +#define SFNT_MAC_TRUE 0x74727565UL #define SFNT_OPENTYPE 0x00010000UL #define SFNT_POSTSCRIPT 0x4f54544fUL #define SFNT_TTC 0x74746366UL @@ -56,14 +61,11 @@ sfnt *sfnt_open(unsigned char *buff, int buflen) { sfnt *sfont; ULONG type; - sfont = xmalloc(sizeof(sfnt)); sfont->loc = 0; sfont->buffer = buff; sfont->buflen = buflen; - type = sfnt_get_ulong(sfont); - if (type == SFNT_TRUETYPE || type == SFNT_MAC_TRUE) { sfont->type = SFNT_TYPE_TRUETYPE; } else if (type == SFNT_OPENTYPE) { @@ -73,7 +75,6 @@ sfnt *sfnt_open(unsigned char *buff, int buflen) } else if (type == SFNT_TTC) { sfont->type = SFNT_TYPE_TTC; } - sfont->loc = 0; sfont->directory = NULL; return sfont; @@ -82,7 +83,6 @@ sfnt *sfnt_open(unsigned char *buff, int buflen) static void release_directory(struct sfnt_table_directory *td) { long i; - if (td) { if (td->tables) { for (i = 0; i < td->num_tables; i++) { @@ -95,19 +95,16 @@ static void release_directory(struct sfnt_table_directory *td) RELEASE(td->flags); RELEASE(td); } - return; } void sfnt_close(sfnt * sfont) { - if (sfont) { if (sfont->directory) release_directory(sfont->directory); RELEASE(sfont); } - return; } @@ -115,70 +112,67 @@ int put_big_endian(void *s, LONG q, int n) { int i; char *p; - p = (char *) s; for (i = n - 1; i >= 0; i--) { p[i] = (char) (q & 0xff); q >>= 8; } - return n; } -@ Convert four-byte number to big endianess in a machine independent way. +/*tex + + Convert four-byte number to big endianess in a machine independent way. + +*/ -@c static void convert_tag(char *tag, unsigned long u_tag) { int i; - for (i = 3; i >= 0; i--) { tag[i] = (char) (u_tag % 256); u_tag /= 256; } - return; } +/*tex -@ Computes the max power of 2 <= n + Computes the max power of $|2 <= n$: + +*/ -@c static unsigned max2floor(unsigned n) { int val = 1; - while (n > 1) { n /= 2; val *= 2; } - return (unsigned) val; } +/*tex -@ Computes the log2 of the max power of 2 <= n + Computes the log2 of the max power of $2 <= n$ + +*/ -@c static unsigned log2floor(unsigned n) { unsigned val = 0; - while (n > 1) { n /= 2; val++; } - return val; } -@ @c static ULONG sfnt_calc_checksum(void *data, ULONG length) { ULONG chksum = 0; BYTE *p, *endptr; ULONG count = 0; - p = (BYTE *) data; endptr = p + length; while (p < endptr) { @@ -186,61 +180,45 @@ static ULONG sfnt_calc_checksum(void *data, ULONG length) count = ((count + 1) & 3); p++; } - return chksum; } -@ @c static int find_table_index(struct sfnt_table_directory *td, const char *tag) { int idx; - if (!td) return -1; - for (idx = 0; idx < td->num_tables; idx++) { if (!memcmp(td->tables[idx].tag, tag, 4)) return idx; } - return -1; } -@ @c void sfnt_set_table(sfnt * sfont, const char *tag, void *data, ULONG length) { struct sfnt_table_directory *td; int idx; - - ASSERT(sfont); - td = sfont->directory; idx = find_table_index(td, tag); - if (idx < 0) { idx = td->num_tables; td->num_tables++; td->tables = RENEW(td->tables, td->num_tables, struct sfnt_table); memcpy(td->tables[idx].tag, tag, 4); } - td->tables[idx].check_sum = sfnt_calc_checksum(data, length); td->tables[idx].offset = 0L; td->tables[idx].length = length; td->tables[idx].data = data; - return; } -@ @c ULONG sfnt_find_table_len(sfnt * sfont, const char *tag) { ULONG length; struct sfnt_table_directory *td; int idx; - - ASSERT(sfont && tag); - td = sfont->directory; idx = find_table_index(td, tag); if (idx < 0) @@ -248,19 +226,14 @@ ULONG sfnt_find_table_len(sfnt * sfont, const char *tag) else { length = td->tables[idx].length; } - return length; } -@ @c ULONG sfnt_find_table_pos(sfnt * sfont, const char *tag) { ULONG offset; struct sfnt_table_directory *td; int idx; - - ASSERT(sfont && tag); - td = sfont->directory; idx = find_table_index(td, tag); if (idx < 0) @@ -268,75 +241,51 @@ ULONG sfnt_find_table_pos(sfnt * sfont, const char *tag) else { offset = td->tables[idx].offset; } - return offset; } -@ @c ULONG sfnt_locate_table(sfnt * sfont, const char *tag) { ULONG offset; - - ASSERT(sfont && tag); - offset = sfnt_find_table_pos(sfont, tag); if (offset == 0) normal_error("ttf","sfnt table not found"); - sfnt_seek_set(sfont, (long) offset); - return offset; } -@ @c int sfnt_read_table_directory(sfnt * sfont, ULONG offset) { struct sfnt_table_directory *td; unsigned long i, u_tag; - - ASSERT(sfont); - if (sfont->directory) release_directory(sfont->directory); sfont->directory = td = NEW(1, struct sfnt_table_directory); - - ASSERT(sfont->buffer); sfnt_seek_set(sfont, (long) offset); - td->version = sfnt_get_ulong(sfont); td->num_tables = sfnt_get_ushort(sfont); td->search_range = sfnt_get_ushort(sfont); td->entry_selector = sfnt_get_ushort(sfont); td->range_shift = sfnt_get_ushort(sfont); - td->flags = NEW(td->num_tables, char); td->tables = NEW(td->num_tables, struct sfnt_table); - for (i = 0; i < td->num_tables; i++) { u_tag = sfnt_get_ulong(sfont); - convert_tag(td->tables[i].tag, u_tag); td->tables[i].check_sum = sfnt_get_ulong(sfont); td->tables[i].offset = sfnt_get_ulong(sfont); td->tables[i].length = sfnt_get_ulong(sfont); td->tables[i].data = NULL; - td->flags[i] = 0; } - td->num_kept_tables = 0; - return 0; } -@ @c int sfnt_require_table(sfnt * sfont, const char *tag, int must_exist) { struct sfnt_table_directory *td; int idx; - - ASSERT(sfont && sfont->directory); - td = sfont->directory; idx = find_table_index(td, tag); if (idx < 0) { @@ -346,22 +295,19 @@ int sfnt_require_table(sfnt * sfont, const char *tag, int must_exist) td->flags[idx] |= SFNT_TABLE_REQUIRED; td->num_kept_tables++; } - return 0; } +/*tex + All tables begin on four byte boundries, and pad any remaining space between + tables with zeros. Entries in the Table Directory must be sorted in ascending + order by tag The head table contains checksum of the whole font file. To + compute: first set it to 0, sum the entire font as ULONG, then store + 0xB1B0AFBA - sum. -@ All tables begin on four byte boundries, and pad any remaining space - between tables with zeros - - Entries in the Table Directory must be sorted in ascending order by tag - - The head table contains checksum of the whole font file. - To compute: first set it to 0, sum the entire font as ULONG, - then store 0xB1B0AFBA - sum. +*/ -@c # include "font/luatexfont.h" # undef MIN # define MIN(a, b) (((a) < (b)) ? (a) : (b)) @@ -376,14 +322,8 @@ pdf_obj *sfnt_create_FontFile_stream(sfnt * sfont) long offset, nb_read, length; int i, sr; char *p; - - ASSERT(sfont && sfont->directory); - stream = pdf_new_stream(STREAM_COMPRESS); - td = sfont->directory; - - /* Header */ p = (char *) wbuf; p += sfnt_put_ulong(p, (LONG) td->version); p += sfnt_put_ushort(p, td->num_kept_tables); @@ -391,20 +331,15 @@ pdf_obj *sfnt_create_FontFile_stream(sfnt * sfont) p += sfnt_put_ushort(p, sr); p += sfnt_put_ushort(p, log2floor(td->num_kept_tables)); p += sfnt_put_ushort(p, td->num_kept_tables * 16 - sr); - pdf_add_stream(stream, wbuf, 12); - - /* - Compute start of actual tables (after headers). - */ + /*tex Compute start of actual tables (after headers). */ offset = 12 + 16 * td->num_kept_tables; for (i = 0; i < td->num_tables; i++) { - /* This table must exist in FontFile */ + /*tex This table must exist in |FontFile|: */ if (td->flags[i] & SFNT_TABLE_REQUIRED) { if ((offset % 4) != 0) { offset += 4 - (offset % 4); } - p = (char *) wbuf; memcpy(p, td->tables[i].tag, 4); p += 4; @@ -412,11 +347,9 @@ pdf_obj *sfnt_create_FontFile_stream(sfnt * sfont) p += sfnt_put_ulong(p, offset); p += sfnt_put_ulong(p, (LONG) td->tables[i].length); pdf_add_stream(stream, wbuf, 16); - offset = (long) (offset + (long) td->tables[i].length); } } - offset = 12 + 16 * td->num_kept_tables; for (i = 0; i < td->num_tables; i++) { if (td->flags[i] & SFNT_TABLE_REQUIRED) { @@ -426,13 +359,11 @@ pdf_obj *sfnt_create_FontFile_stream(sfnt * sfont) offset += length; } if (!td->tables[i].data) { - if (!sfont->buffer) - { + if (!sfont->buffer) { pdf_release_obj(stream); normal_error("ttf","file not opened or already closed"); return NULL; } - length = (long) td->tables[i].length; sfnt_seek_set(sfont, (long) td->tables[i].offset); while (length > 0) { @@ -453,10 +384,9 @@ pdf_obj *sfnt_create_FontFile_stream(sfnt * sfont) RELEASE(td->tables[i].data); td->tables[i].data = NULL; } - /* Set offset for next table */ + /*tex Set offset for next table. */ offset = (long) (offset + (long) td->tables[i].length); } } - return stream; } diff --git a/Build/source/texk/web2c/luatexdir/font/subfont.w b/Build/source/texk/web2c/luatexdir/font/subfont.c index 0616bdad43c..d2f5f8d2f5e 100644 --- a/Build/source/texk/web2c/luatexdir/font/subfont.w +++ b/Build/source/texk/web2c/luatexdir/font/subfont.c @@ -1,30 +1,28 @@ -% subfont.w -% -% Copyright 2005-2006 Han The Thanh <thanh@@pdftex.org> -% Copyright 2006-2008 Taco Hoekwater <taco@@luatex.org> -% -% This file is part of LuaTeX. -% -% LuaTeX 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. -% -% LuaTeX 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 Lesser General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License along -% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +/* -@ @c +Copyright 2005-2006 Han The Thanh <thanh@pdftex.org> +Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> +This file is part of LuaTeX. + +LuaTeX 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. + +LuaTeX 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU General Public License along +with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +*/ #include "ptexlib.h" #include <string.h> -@ @c static struct avl_table *sfd_tree = NULL; static unsigned char *sfd_buffer = NULL; @@ -34,12 +32,11 @@ static int sfd_curbyte = 0; #define SFD_BUF_SIZE SMALL_BUF_SIZE #define sfd_close() xfclose(sfd_file, cur_file_name) -#define sfd_open(a) (sfd_file = fopen((char *)(a), FOPEN_RBIN_MODE)) +#define sfd_open(a) (sfd_file = fopen((char *)(a), FOPEN_RBIN_MODE)) #define sfd_read_file() readbinfile(sfd_file,&sfd_buffer,&sfd_size) #define sfd_getchar() sfd_buffer[sfd_curbyte++] -#define sfd_eof() (sfd_curbyte>=sfd_size) - +#define sfd_eof() (sfd_curbyte>=sfd_size) static FILE *sfd_file; static char sfd_line[SFD_BUF_SIZE]; @@ -50,8 +47,10 @@ static subfont_entry *new_subfont_entry(void) subfont_entry *subfont; subfont = xtalloc(1, subfont_entry); subfont->infix = NULL; - for (i = 0; i < 256; ++i) - subfont->charcodes[i] = -1; /* unassigned */ + for (i = 0; i < 256; ++i) { + /*tex Unassigned: */ + subfont->charcodes[i] = -1; + } subfont->next = NULL; return subfont; } @@ -84,8 +83,7 @@ static void destroy_sfd_entry(void *pa, void *pb) static int comp_sfd_entry(const void *pa, const void *pb, void *p) { (void) p; - return strcmp(((const sfd_entry *) pa)->name, - ((const sfd_entry *) pb)->name); + return strcmp(((const sfd_entry *) pa)->name, ((const sfd_entry *) pb)->name); } void sfd_free(void) @@ -117,19 +115,17 @@ static void sfd_getline(boolean expect_eof) goto restart; } -@ @c static sfd_entry *read_sfd(char *sfd_name) { void **aa; sfd_entry *sfd, tmp_sfd; subfont_entry *sf; - char buf[SMALL_BUF_SIZE], *p; long int i, j, k; int n; int callback_id = 0; int file_opened = 0; - /* check whether this sfd has been read */ + /*tex Check whether this |sfd| has been read: */ tmp_sfd.name = sfd_name; if (sfd_tree == NULL) { sfd_tree = avl_create(comp_sfd_entry, NULL, &avl_xallocator); @@ -141,7 +137,6 @@ static sfd_entry *read_sfd(char *sfd_name) xfree(sfd_buffer); sfd_curbyte = 0; sfd_size = 0; - cur_file_name = luatex_find_file(sfd_name, find_sfd_file_callback); if (cur_file_name) { callback_id = callback_defined(read_sfd_file_callback); @@ -168,30 +163,38 @@ static sfd_entry *read_sfd(char *sfd_name) sfd->name = xstrdup(sfd_name); while (!sfd_eof()) { sfd_getline(true); - if (*sfd_line == 10) /* empty line indicating eof */ + if (*sfd_line == 10) { + /*tex An empty line indicates |EOF|. */ break; + } sf = new_subfont_entry(); sf->next = sfd->subfont; sfd->subfont = sf; sscanf(sfd_line, "%s %n", buf, &n); sf->infix = xstrdup(buf); - p = sfd_line + n; /* skip to the next word */ + /*tex Skip to the next word: */ + p = sfd_line + n; k = 0; read_ranges: for (;;) { - if (*p == '\\') { /* continue on next line */ + if (*p == '\\') { + /*tex Continue on the next line: */ sfd_getline(false); p = sfd_line; goto read_ranges; - } else if (*p == 0) /* end of subfont */ + } else if (*p == 0) { + /*tex End of subfont. */ break; + } if (sscanf(p, " %li %n", &i, &n) == 0) formatted_error("sub font","invalid token: %s", p); p += n; - if (*p == ':') { /* offset */ + if (*p == ':') { + /*tex Variant: offset */ k = i; p++; - } else if (*p == '_') { /* range */ + } else if (*p == '_') { + /*tex Variant: range */ if (sscanf(p + 1, " %li %n", &j, &n) == 0) formatted_error("sub font","invalid token: %s", p); if (i > j || k + (j - i) > 255) @@ -199,8 +202,10 @@ static sfd_entry *read_sfd(char *sfd_name) while (i <= j) sf->charcodes[k++] = i++; p += n + 1; - } else /* codepoint */ + } else { + /*tex Variant: codepoint */ sf->charcodes[k++] = i; + } } } tex_printf("}"); @@ -209,7 +214,6 @@ static sfd_entry *read_sfd(char *sfd_name) return sfd; } -@ @c boolean handle_subfont_fm(fm_entry * fm, int mode) { size_t l; @@ -220,16 +224,20 @@ boolean handle_subfont_fm(fm_entry * fm, int mode) char buf[SMALL_BUF_SIZE]; assert(fm->tfm_name != NULL); p = fm->tfm_name; - q = strchr(p, '@@'); /* search for the first '@@' */ + /*tex Search for the first |@|. */ + q = strchr(p, '@'); if (q == NULL) return false; - r = strchr(q + 1, '@@'); /* search for the second '@@' */ + /*tex Search for the second |@|: */ + r = strchr(q + 1, '@'); if (r == NULL) return false; - if (q <= p || r <= q + 1 /* prefix or sfd name is empty */ - || r - p != (int) strlen(p) - 1) /* or the second '@@' is not the last char yet */ + /*tex Check if prefix or sfd name is empty or the second |@| is not the last char yet. */ + if (q <= p || r <= q + 1 || r - p != (int) strlen(p) - 1) { return false; - l = (size_t) (r - (q + 1)); /* length of sfd name */ + } + /*tex The length of sfd name: */ + l = (size_t) (r - (q + 1)); strncpy(buf, q + 1, l); buf[l] = 0; check_buf(strlen(buf) + 4, SMALL_BUF_SIZE); @@ -237,15 +245,16 @@ boolean handle_subfont_fm(fm_entry * fm, int mode) sfd = read_sfd(buf); if (sfd == NULL) return false; - /* at this point we know fm is a subfont */ + /*tex At this point we know fm is a subfont. */ set_subfont(fm); xfree(fm->ps_name); - /* set default values for PidEid */ + /*tex Set default values for |Pid| and |Eid|: */ if (fm->pid == -1) { fm->pid = 3; fm->eid = 1; } - l = (size_t) (q - p); /* length of base tfm name (prefix) */ + /*tex Calculate the length of base tfm name (prefix). */ + l = (size_t) (q - p); for (sf = sfd->subfont; sf != NULL; sf = sf->next) { strncpy(buf, p, l); buf[l] = 0; @@ -257,8 +266,11 @@ boolean handle_subfont_fm(fm_entry * fm, int mode) fm2->pid = fm->pid; fm2->eid = fm->eid; fm2->subfont = sf; - if (avl_do_entry(fm2, mode) != 0) /* try to insert the entry */ - delete_fm_entry(fm2); /* delete it if failed */ + /*tex Try to insert the entry. */ + if (avl_do_entry(fm2, mode) != 0) { + /*tex And delete it if we failed. */ + delete_fm_entry(fm2); + } } delete_fm_entry(fm); return true; diff --git a/Build/source/texk/web2c/luatexdir/font/texfont.w b/Build/source/texk/web2c/luatexdir/font/texfont.c index ce463326a86..332a8a3446e 100644 --- a/Build/source/texk/web2c/luatexdir/font/texfont.w +++ b/Build/source/texk/web2c/luatexdir/font/texfont.c @@ -1,41 +1,52 @@ -% texfont.w -% -% Copyright 2006-2013 Taco Hoekwater <taco@@luatex.org> -% -% This file is part of LuaTeX. -% -% LuaTeX 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. -% -% LuaTeX 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 Lesser General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License along -% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. - -@* Main font API implementation for the original pascal parts. - -Stuff to watch out for: - -\item{} Knuth had a |'null_character'| that was used when a character could -not be found by the |fetch()| routine, to signal an error. This has -been deleted, but it may mean that the output of luatex is -incompatible with TeX after |fetch()| has detected an error condition. - -\item{} Knuth also had a |font_glue()| optimization. I've removed that -because it was a bit of dirty programming and it also was -problematic |if 0 != null|. - -@c +/* + +Copyright 2006-2013 Taco Hoekwater <taco@luatex.org> + +This file is part of LuaTeX. + +LuaTeX 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. + +LuaTeX 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU General Public License along +with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +*/ + +/*tex + + Here is the main font API implementation for the original pascal parts. Stuff + to watch out for: + + \startitemize + + \startitem + Knuth had a |'null_character'| that was used when a character could + not be found by the |fetch()| routine, to signal an error. This has + been deleted, but it may mean that the output of luatex is + incompatible with TeX after |fetch()| has detected an error + condition. + \stopitem + + \startitem + Knuth also had a |font_glue()| optimization. I've removed that + because it was a bit of dirty programming and it also was problematic + |if 0 != null|. + \stopitem + + \stopitemize + +*/ #include "ptexlib.h" #include "lua/luatex-api.h" -@ @c #define noDEBUG #define proper_char_index(c) (c<=font_ec(f) && c>=font_bc(f)) @@ -46,7 +57,6 @@ texfont **font_tables = NULL; static int font_arr_max = 0; static int font_id_maxval = 0; -@ @c static void grow_font_table(int id) { int j; @@ -89,7 +99,6 @@ void set_max_font_id(int i) font_id_maxval = i; } -@ @c int new_font(void) { int k; @@ -98,7 +107,7 @@ int new_font(void) sa_tree_item sa_value = { 0 }; id = new_font_id(); font_bytes += (int) sizeof(texfont); - /* most stuff is zero */ + /*tex Most stuff is zero */ font_tables[id] = xcalloc(1, sizeof(texfont)); font_tables[id]->_font_name = NULL; font_tables[id]->_font_area = NULL; @@ -112,43 +121,44 @@ int new_font(void) font_tables[id]->_right_boundary = NULL; font_tables[id]->_param_base = NULL; font_tables[id]->_math_param_base = NULL; - - set_font_bc(id, 1); /* ec = 0 */ + /*tex |ec = 0| */ + set_font_bc(id, 1); set_font_writingmode(id, 0); set_font_identity(id, 0); set_hyphen_char(id, '-'); set_skew_char(id, -1); - font_slant(id) = 0; /* vertical */ - font_extend(id) = 1000; /* normal width */ - - /* allocate eight values including 0 */ + /*tex vertical */ + font_slant(id) = 0; + /*tex normal width */ + font_extend(id) = 1000; + /*tex normal height */ + font_squeeze(id) = 1000; + font_width(id) = 0; + font_mode(id) = 0; + /*tex allocate eight values including 0 */ set_font_params(id, 7); for (k = 0; k <= 7; k++) { set_font_param(id, k, 0); } - /* character info zero is reserved for notdef */ - font_tables[id]->characters = new_sa_tree(1, 1, sa_value); /* stack size 1, default item value 0 */ + /*tex character info zero is reserved for |notdef|. The stack size 1, default item value 0. */ + font_tables[id]->characters = new_sa_tree(1, 1, sa_value); ci = xcalloc(1, sizeof(charinfo)); set_charinfo_name(ci, xstrdup(".notdef")); font_tables[id]->charinfo = ci; font_tables[id]->charinfo_size = 1; font_tables[id]->charinfo_cache = NULL; - return id; } -@ @c void font_malloc_charinfo(internal_font_number f, int num) { int glyph = font_tables[f]->charinfo_size; font_bytes += (int) (num * (int) sizeof(charinfo)); do_realloc(font_tables[f]->charinfo, (unsigned) (glyph + num), charinfo); - memset(&(font_tables[f]->charinfo[glyph]), 0, - (size_t) (num * (int) sizeof(charinfo))); + memset(&(font_tables[f]->charinfo[glyph]), 0, (size_t) (num * (int) sizeof(charinfo))); font_tables[f]->charinfo_size += num; } -@ @c #define find_charinfo_id(f,c) (get_sa_item(font_tables[f]->characters,c).int_value) charinfo *get_charinfo(internal_font_number f, int c) @@ -163,9 +173,10 @@ charinfo *get_charinfo(internal_font_number f, int c) if (tglyph >= font_tables[f]->charinfo_size) { font_malloc_charinfo(f, 256); } - font_tables[f]->charinfo[tglyph].ef = 1000; /* init */ + font_tables[f]->charinfo[tglyph].ef = 1000; sa_value.int_value = tglyph; - set_sa_item(font_tables[f]->characters, c, sa_value, 1); /* 1 = global */ + /*tex 1 means global */ + set_sa_item(font_tables[f]->characters, c, sa_value, 1); glyph = tglyph; } return &(font_tables[f]->charinfo[glyph]); @@ -187,7 +198,6 @@ charinfo *get_charinfo(internal_font_number f, int c) return &(font_tables[f]->charinfo[0]); } -@ @c static void set_charinfo(internal_font_number f, int c, charinfo * ci) { int glyph; @@ -205,7 +215,6 @@ static void set_charinfo(internal_font_number f, int c, charinfo * ci) } } -@ @c charinfo *copy_charinfo(charinfo * ci) { int x, k; @@ -231,7 +240,7 @@ charinfo *copy_charinfo(charinfo * ci) if (ci->tounicode != NULL) { co->tounicode = xstrdup(ci->tounicode); } - /* kerns */ + /*tex Kerns */ if ((kern = get_charinfo_kerns(ci)) != NULL) { x = 0; while (!kern_end(kern[x])) { @@ -241,7 +250,7 @@ charinfo *copy_charinfo(charinfo * ci) co->kerns = xmalloc((unsigned) (x * (int) sizeof(kerninfo))); memcpy(co->kerns, ci->kerns, (size_t) (x * (int) sizeof(kerninfo))); } - /* ligs */ + /*tex Ligatures */ if ((lig = get_charinfo_ligatures(ci)) != NULL) { x = 0; while (!lig_end(lig[x])) { @@ -252,14 +261,13 @@ charinfo *copy_charinfo(charinfo * ci) memcpy(co->ligatures, ci->ligatures, (size_t) (x * (int) sizeof(liginfo))); } - /* packets */ + /*tex Packets */ if ((packet = get_charinfo_packets(ci)) != NULL) { x = vf_packet_bytes(ci); co->packets = xmalloc((unsigned) x); memcpy(co->packets, ci->packets, (size_t) x); } - - /* horizontal and vertical extenders */ + /*tex Horizontal and vertical extenders */ if (get_charinfo_vert_variants(ci) != NULL) { set_charinfo_vert_variants(co, copy_variants(get_charinfo_vert_variants(ci))); } @@ -320,7 +328,6 @@ charinfo *char_info(internal_font_number f, int c) return &(font_tables[f]->charinfo[0]); } -@ @c scaled_whd get_charinfo_whd(internal_font_number f, int c) { scaled_whd s; @@ -332,7 +339,6 @@ scaled_whd get_charinfo_whd(internal_font_number f, int c) return s; } -@ @c int char_exists(internal_font_number f, int c) { if (f > font_id_maxval) @@ -347,35 +353,35 @@ int char_exists(internal_font_number f, int c) return 0; } -@ @c int lua_glyph_not_found_callback(internal_font_number f, int c) { int callback_id; int ret = 0; + int top, i; callback_id = callback_defined(glyph_not_found_callback); if (callback_id != 0) { + top = lua_gettop(Luas); if (!get_callback(Luas, callback_id)) { - lua_pop(Luas, 2); + lua_settop(Luas, top); return 0; } lua_pushinteger(Luas, f); lua_pushinteger(Luas, c); - if (lua_pcall(Luas, 2, 1, 0) != 0) { /* two args, 1 result */ - fprintf(stdout, "error: %s\n", lua_tostring(Luas, -1)); - lua_pop(Luas, 2); - error(); + if ((i=lua_pcall(Luas, 2, 1, 0)) != 0) { + formatted_warning ("glyph not found", "error: %s", lua_tostring(Luas, -1)); + lua_settop(Luas, top); + luatex_error(Luas, (i == LUA_ERRRUN ? 0 : 1)); } else { ret = lua_toboolean(Luas, -1); } + lua_settop(Luas, top); } else { char_warning(f,c); } return ret; } -@ @c -extinfo *new_variant(int glyph, int startconnect, int endconnect, - int advance, int repeater) +extinfo *new_variant(int glyph, int startconnect, int endconnect, int advance, int repeater) { extinfo *ext; ext = xmalloc(sizeof(extinfo)); @@ -388,8 +394,6 @@ extinfo *new_variant(int glyph, int startconnect, int endconnect, return ext; } - -@ @c static extinfo *copy_variant(extinfo * old) { extinfo *ext; @@ -403,7 +407,6 @@ static extinfo *copy_variant(extinfo * old) return ext; } -@ @c static void dump_variant(extinfo * ext) { dump_int(ext->glyph); @@ -414,8 +417,6 @@ static void dump_variant(extinfo * ext) return; } - -@ @c static extinfo *undump_variant(void) { int x; @@ -437,7 +438,6 @@ static extinfo *undump_variant(void) return ext; } -@ @c void add_charinfo_vert_variant(charinfo * ci, extinfo * ext) { if (ci->vert_variants == NULL) { @@ -451,7 +451,6 @@ void add_charinfo_vert_variant(charinfo * ci, extinfo * ext) } -@ @c void add_charinfo_hor_variant(charinfo * ci, extinfo * ext) { if (ci->hor_variants == NULL) { @@ -465,7 +464,6 @@ void add_charinfo_hor_variant(charinfo * ci, extinfo * ext) } -@ @c extinfo *copy_variants(extinfo * o) { extinfo *c, *t = NULL, *h = NULL; @@ -482,7 +480,6 @@ extinfo *copy_variants(extinfo * o) return h; } -@ @c static void dump_charinfo_variants(extinfo * o) { while (o != NULL) { @@ -493,7 +490,6 @@ static void dump_charinfo_variants(extinfo * o) return; } -@ @c static extinfo *undump_charinfo_variants(void) { extinfo *c, *t = NULL, *h = NULL; @@ -510,9 +506,12 @@ static extinfo *undump_charinfo_variants(void) } -@ Note that mant more small things like this are implemented -as macros in the header file. -@c +/*tex + + Note that many more small things like this are implemented as macros in the + header file. +*/ + void set_charinfo_width(charinfo * ci, scaled val) { ci->width = val; @@ -610,7 +609,6 @@ void set_charinfo_rp(charinfo * ci, scaled val) ci->rp = val; } -@ @c void set_charinfo_vert_variants(charinfo * ci, extinfo * ext) { extinfo *c, *lst; @@ -625,7 +623,6 @@ void set_charinfo_vert_variants(charinfo * ci, extinfo * ext) ci->vert_variants = ext; } -@ @c void set_charinfo_hor_variants(charinfo * ci, extinfo * ext) { extinfo *c, *lst; @@ -641,11 +638,10 @@ void set_charinfo_hor_variants(charinfo * ci, extinfo * ext) } -@ @c int get_charinfo_math_kerns(charinfo * ci, int id) { - - int k = 0; /* all callers check for |result>0| */ + /*tex All callers check for |result>0|. */ + int k = 0; if (id == top_left_kern) { k = ci->top_left_math_kerns; } else if (id == bottom_left_kern) { @@ -660,7 +656,6 @@ int get_charinfo_math_kerns(charinfo * ci, int id) return k; } -@ @c void add_charinfo_math_kern(charinfo * ci, int id, scaled ht, scaled krn) { int k; @@ -693,8 +688,6 @@ void add_charinfo_math_kern(charinfo * ci, int id, scaled ht, scaled krn) } } - -@ @c static void dump_math_kerns(charinfo * ci) { int k, l; @@ -724,11 +717,9 @@ static void dump_math_kerns(charinfo * ci) } } -@ @c static void undump_math_kerns(charinfo * ci) { - int k; - int x; + int k, x; undump_int(x); ci->top_left_math_kerns = x; if (x > 0) @@ -771,21 +762,23 @@ static void undump_math_kerns(charinfo * ci) } } +/*tex -@ In TeX, extensibles were fairly simple things. - This function squeezes a TFM extensible into the vertical extender structures. - |advance==0| is a special case for TFM fonts, because finding the proper - advance width during tfm reading can be tricky + In TeX, extensibles were fairly simple things. This function squeezes a TFM + extensible into the vertical extender structures. |advance==0| is a special + case for TFM fonts, because finding the proper advance width during tfm + reading can be tricky. + A small complication arises if |rep| is the only non-zero: it needs to be + doubled as a non-repeatable to avoid mayhem. - a small complication arises if |rep| is the only non-zero: it needs to be - doubled as a non-repeatable to avoid mayhem */ +*/ -@c void set_charinfo_extensible(charinfo * ci, int top, int bot, int mid, int rep) { extinfo *ext; - set_charinfo_vert_variants(ci, NULL); /* clear old */ + /*tex Clear old data: */ + set_charinfo_vert_variants(ci, NULL); if (bot == 0 && top == 0 && mid == 0 && rep != 0) { ext = new_variant(rep, 0, 0, 0, EXT_NORMAL); add_charinfo_vert_variant(ci, ext); @@ -815,10 +808,13 @@ void set_charinfo_extensible(charinfo * ci, int top, int bot, int mid, int rep) } } -@ Note that many more simple things like this are implemented as macros -in the header file. +/*tex + + Note that many more simple things like this are implemented as macros in the + header file. + +*/ -@c scaled get_charinfo_width(charinfo * ci) { return ci->width; @@ -987,7 +983,6 @@ scaled char_bot_accent(internal_font_number f, int c) return get_charinfo_bot_accent(ci); } - int char_remainder(internal_font_number f, int c) { charinfo *ci = char_info(f, c); @@ -1036,7 +1031,6 @@ eight_bits *char_packets(internal_font_number f, int c) return get_charinfo_packets(ci); } -@ @c void set_font_params(internal_font_number f, int b) { int i; @@ -1055,7 +1049,6 @@ void set_font_params(internal_font_number f, int b) } } -@ @c void set_font_math_params(internal_font_number f, int b) { int i; @@ -1074,13 +1067,11 @@ void set_font_math_params(internal_font_number f, int b) } } -@ @c int copy_font(int f) { int i, ci_cnt, ci_size; charinfo *ci; int k = new_font(); - { ci = font_tables[k]->charinfo; ci_cnt = font_tables[k]->charinfo_count; @@ -1090,12 +1081,10 @@ int copy_font(int f) font_tables[k]->charinfo_count = ci_cnt; font_tables[k]->charinfo_size = ci_size; } - font_malloc_charinfo(k, font_tables[f]->charinfo_count); set_font_cache_id(k, 0); set_font_used(k, 0); set_font_touched(k, 0); - font_tables[k]->_font_name = NULL; font_tables[k]->_font_filename = NULL; font_tables[k]->_font_fullname = NULL; @@ -1106,7 +1095,6 @@ int copy_font(int f) font_tables[k]->_font_cidordering = NULL; font_tables[k]->_left_boundary = NULL; font_tables[k]->_right_boundary = NULL; - set_font_name(k, xstrdup(font_name(f))); if (font_filename(f) != NULL) set_font_filename(k, xstrdup(font_filename(f))); @@ -1122,12 +1110,10 @@ int copy_font(int f) set_font_cidregistry(k, xstrdup(font_cidregistry(f))); if (font_cidordering(f) != NULL) set_font_cidordering(k, xstrdup(font_cidordering(f))); - i = (int) (sizeof(*param_base(f)) * (unsigned) (font_params(f)+1)); font_bytes += i; param_base(k) = xmalloc((unsigned) (i+1)); memcpy(param_base(k), param_base(f), (size_t) (i)); - if (font_math_params(f) > 0) { i = (int) (sizeof(*math_param_base(f)) * (unsigned) font_math_params(f)); @@ -1135,27 +1121,23 @@ int copy_font(int f) math_param_base(k) = xmalloc((unsigned) i); memcpy(math_param_base(k), math_param_base(f), (size_t) i); } - for (i = 0; i <= font_tables[f]->charinfo_count; i++) { ci = copy_charinfo(&font_tables[f]->charinfo[i]); font_tables[k]->charinfo[i] = *ci; } - if (left_boundary(f) != NULL) { ci = copy_charinfo(left_boundary(f)); set_charinfo(k, left_boundarychar, ci); } - if (right_boundary(f) != NULL) { ci = copy_charinfo(right_boundary(f)); set_charinfo(k, right_boundarychar, ci); } - /* not updated yet: */ + /*tex Not updated yet: */ font_tables[k]->charinfo_count = font_tables[f]->charinfo_count; return k; } -@ @c void delete_font(int f) { int i; @@ -1172,7 +1154,6 @@ void delete_font(int f) set_font_cidordering(f, NULL); set_left_boundary(f, NULL); set_right_boundary(f, NULL); - for (i = font_bc(f); i <= font_ec(f); i++) { if (quick_char_exists(f, i)) { co = char_info(f, i); @@ -1185,24 +1166,21 @@ void delete_font(int f) set_charinfo_hor_variants(co, NULL); } } - /* free .notdef */ + /*tex free |notdef| */ set_charinfo_name(font_tables[f]->charinfo + 0, NULL); free(font_tables[f]->charinfo); destroy_sa_tree(font_tables[f]->characters); - free(param_base(f)); if (math_param_base(f) != NULL) free(math_param_base(f)); free(font_tables[f]); font_tables[f] = NULL; - if (font_id_maxval == f) { font_id_maxval--; } } } -@ @c void create_null_font(void) { int i = new_font(); @@ -1212,7 +1190,6 @@ void create_null_font(void) set_font_touched(i, 1); } -@ @c boolean is_valid_font(int id) { int ret = 0; @@ -1221,7 +1198,6 @@ boolean is_valid_font(int id) return ret; } -@ @c boolean cmp_font_area(int id, str_number t) { char *tt = NULL; @@ -1241,9 +1217,13 @@ boolean cmp_font_area(int id, str_number t) return 1; } -@ Here come some subroutines to deal with expanded fonts for HZ-algorithm. -return 1 == identical -@c +/*tex + + Here come some subroutines to deal with expanded fonts for HZ-algorithm. + returning 1 means that they are identical. + +*/ + static boolean cmp_font_name(int id, char *tt) { char *tid; @@ -1257,18 +1237,16 @@ static boolean cmp_font_name(int id, char *tt) return 1; } -@ @c int test_no_ligatures(internal_font_number f) { int c; for (c = font_bc(f); c <= font_ec(f); c++) { - if (has_lig(f, c)) /* |char_exists(f,c)| */ + if (has_lig(f, c)) return 0; } return 1; } -@ @c int get_tag_code(internal_font_number f, int c) { small_number i; @@ -1286,7 +1264,6 @@ int get_tag_code(internal_font_number f, int c) return -1; } -@ @c int get_lp_code(internal_font_number f, int c) { charinfo *ci = char_info(f, c); @@ -1305,13 +1282,11 @@ int get_ef_code(internal_font_number f, int c) return get_charinfo_ef(ci); } -@ @c void set_tag_code(internal_font_number f, int c, int i) { int fixedi; charinfo *co; if (char_exists(f, c)) { - /* |abs(fix_int(i-7,0))| */ fixedi = -(i < -7 ? -7 : (i > 0 ? 0 : i)); co = char_info(f, c); if (fixedi >= 4) { @@ -1333,7 +1308,6 @@ void set_tag_code(internal_font_number f, int c, int i) } } -@ @c void set_lp_code(internal_font_number f, int c, int i) { charinfo *co; @@ -1361,7 +1335,6 @@ void set_ef_code(internal_font_number f, int c, int i) } } -@ @c void set_no_ligatures(internal_font_number f) { int c; @@ -1370,7 +1343,7 @@ void set_no_ligatures(internal_font_number f) return; co = char_info(f, left_boundarychar); set_charinfo_ligatures(co, NULL); - co = char_info(f, right_boundarychar); /* this is weird */ + co = char_info(f, right_boundarychar); set_charinfo_ligatures(co, NULL); for (c = 0; c < font_tables[f]->charinfo_count; c++) { co = font_tables[f]->charinfo + c; @@ -1379,7 +1352,6 @@ void set_no_ligatures(internal_font_number f) font_tables[f]->ligatures_disabled = 1; } -@ @c liginfo get_ligature(internal_font_number f, int lc, int rc) { int k = 0; @@ -1407,7 +1379,6 @@ liginfo get_ligature(internal_font_number f, int lc, int rc) return t; } -@ @c scaled raw_get_kern(internal_font_number f, int lc, int rc) { int k = 0; @@ -1431,7 +1402,6 @@ scaled raw_get_kern(internal_font_number f, int lc, int rc) return 0; } -@ @c scaled get_kern(internal_font_number f, int lc, int rc) { if (lc == non_boundarychar || rc == non_boundarychar || (!has_kern(f, lc))) @@ -1440,15 +1410,14 @@ scaled get_kern(internal_font_number f, int lc, int rc) } -@ dumping and undumping fonts +/*tex Dumping and undumping fonts. */ -@c -#define dump_string(a) \ - if (a!=NULL) { \ - x = (int)(strlen(a)+1); \ - dump_int(x); dump_things(*a, x); \ - } else { \ - x = 0; dump_int(x); \ +#define dump_string(a) \ + if (a!=NULL) { \ + x = (int)(strlen(a)+1); \ + dump_int(x); dump_things(*a, x); \ + } else { \ + x = 0; dump_int(x); \ } static void dump_charinfo(int f, int c) @@ -1476,8 +1445,7 @@ static void dump_charinfo(int f, int c) dump_int(get_charinfo_index(co)); dump_string(get_charinfo_name(co)); dump_string(get_charinfo_tounicode(co)); - - /* ligatures */ + /*tex Ligatures */ x = 0; if ((lig = get_charinfo_ligatures(co)) != NULL) { while (!lig_end(lig[x])) { @@ -1489,7 +1457,7 @@ static void dump_charinfo(int f, int c) } else { dump_int(x); } - /* kerns */ + /*tex Kerns */ x = 0; if ((kern = get_charinfo_kerns(co)) != NULL) { while (!kern_end(kern[x])) { @@ -1501,13 +1469,12 @@ static void dump_charinfo(int f, int c) } else { dump_int(x); } - /* packets */ + /*tex Packets */ x = vf_packet_bytes(co); dump_int(x); if (x > 0) { dump_things(*get_charinfo_packets(co), x); } - if (get_charinfo_tag(co) == ext_tag) { dump_charinfo_variants(get_charinfo_vert_variants(co)); dump_charinfo_variants(get_charinfo_hor_variants(co)); @@ -1532,6 +1499,9 @@ static void dump_font_entry(texfont * f) dump_int(f->_font_oldmath); dump_int(f->_font_slant); dump_int(f->_font_extend); + dump_int(f->_font_squeeze); + dump_int(f->_font_mode); + dump_int(f->_font_width); dump_int(f->font_max_shrink); dump_int(f->font_max_stretch); dump_int(f->_font_step); @@ -1556,7 +1526,6 @@ static void dump_font_entry(texfont * f) void dump_font(int f) { int i, x; - set_font_used(f, 0); font_tables[f]->charinfo_cache = NULL; dump_font_entry(font_tables[f]); @@ -1568,9 +1537,7 @@ void dump_font(int f) dump_string(font_encodingname(f)); dump_string(font_cidregistry(f)); dump_string(font_cidordering(f)); - dump_things(*param_base(f), (font_params(f) + 1)); - if (font_math_params(f) > 0) { dump_things(*math_param_base(f), (font_math_params(f) + 1 )); } @@ -1586,7 +1553,6 @@ void dump_font(int f) } else { dump_int(0); } - for (i = font_bc(f); i <= font_ec(f); i++) { if (quick_char_exists(f, i)) { dump_charinfo(f, i); @@ -1594,7 +1560,6 @@ void dump_font(int f) } } -@ @c static int undump_charinfo(int f) { charinfo *co; @@ -1603,7 +1568,6 @@ static int undump_charinfo(int f) liginfo *lig = NULL; kerninfo *kern = NULL; eight_bits *packet = NULL; - undump_int(i); co = get_charinfo(f, i); undump_int(x); @@ -1634,8 +1598,7 @@ static int undump_charinfo(int f) set_charinfo_used(co, x); undump_int(x); set_charinfo_index(co, x); - - /* name */ + /*tex Name */ undump_int(x); if (x > 0) { font_bytes += x; @@ -1643,7 +1606,7 @@ static int undump_charinfo(int f) undump_things(*s, x); } set_charinfo_name(co, s); - /* tounicode */ + /*tex Tounicode */ undump_int(x); if (x > 0) { font_bytes += x; @@ -1651,7 +1614,7 @@ static int undump_charinfo(int f) undump_things(*s, x); } set_charinfo_tounicode(co, s); - /* ligatures */ + /*tex Ligatures */ undump_int(x); if (x > 0) { font_bytes += (int) ((unsigned) x * sizeof(liginfo)); @@ -1659,7 +1622,7 @@ static int undump_charinfo(int f) undump_things(*lig, x); } set_charinfo_ligatures(co, lig); - /* kerns */ + /*tex Kerns */ undump_int(x); if (x > 0) { font_bytes += (int) ((unsigned) x * sizeof(kerninfo)); @@ -1668,7 +1631,7 @@ static int undump_charinfo(int f) } set_charinfo_kerns(co, kern); - /* packets */ + /*tex Packets */ undump_int(x); if (x > 0) { font_bytes += x; @@ -1676,7 +1639,6 @@ static int undump_charinfo(int f) undump_things(*packet, x); } set_charinfo_packets(co, packet); - if (get_charinfo_tag(co) == ext_tag) { set_charinfo_vert_variants(co, undump_charinfo_variants()); set_charinfo_hor_variants(co, undump_charinfo_variants()); @@ -1685,19 +1647,18 @@ static int undump_charinfo(int f) return i; } -#define undump_font_string(a) \ - undump_int (x); \ - if (x>0) { \ - font_bytes += x; \ +#define undump_font_string(a) \ + undump_int (x); \ + if (x>0) { \ + font_bytes += x; \ s = xmalloc((unsigned)x); \ - undump_things(*s,x); \ - a(f,s); \ + undump_things(*s,x); \ + a(f,s); \ } static void undump_font_entry(texfont * f) { int x = 0; - /* *INDENT-OFF* */ undump_int(x); f->_font_size = x; undump_int(x); f->_font_dsize = x; undump_int(x); f->_font_cidversion = x; @@ -1711,6 +1672,9 @@ static void undump_font_entry(texfont * f) undump_int(x); f->_font_oldmath = x; undump_int(x); f->_font_slant = x; undump_int(x); f->_font_extend = x; + undump_int(x); f->_font_squeeze = x; + undump_int(x); f->_font_mode = x; + undump_int(x); f->_font_width = x; undump_int(x); f->font_max_shrink = x; undump_int(x); f->font_max_stretch = x; undump_int(x); f->_font_step = x; @@ -1730,7 +1694,6 @@ static void undump_font_entry(texfont * f) undump_int(x); f->ligatures_disabled = x; undump_int(x); f->_pdf_font_num = x; undump_int(x); f->_pdf_font_attr = x; - /* *INDENT-ON* */ } void undump_font(int f) @@ -1746,7 +1709,6 @@ void undump_font(int f) font_bytes += (int) sizeof(texfont); undump_font_entry(tt); font_tables[f] = tt; - undump_font_string(set_font_name); undump_font_string(set_font_area); undump_font_string(set_font_filename); @@ -1755,12 +1717,10 @@ void undump_font(int f) undump_font_string(set_font_encodingname); undump_font_string(set_font_cidregistry); undump_font_string(set_font_cidordering); - i = (int) (sizeof(*param_base(f)) * ((unsigned) font_params(f) + 1)); font_bytes += i; param_base(f) = xmalloc((unsigned) i); undump_things(*param_base(f), (font_params(f) + 1)); - if (font_math_params(f) > 0) { i = (int) (sizeof(*math_param_base(f)) * ((unsigned) font_math_params(f) + 1)); @@ -1768,35 +1728,40 @@ void undump_font(int f) math_param_base(f) = xmalloc((unsigned) i); undump_things(*math_param_base(f), (font_math_params(f) + 1)); } - - /* stack size 1, default item value 0 */ + /*tex stack size 1, default item value 0 */ font_tables[f]->characters = new_sa_tree(1, 1, sa_value); ci = xcalloc(1, sizeof(charinfo)); set_charinfo_name(ci, xstrdup(".notdef")); font_tables[f]->charinfo = ci; undump_int(x); if (x) { - i = undump_charinfo(f); /* left boundary */ + /*tex left boundary */ + i = undump_charinfo(f); } undump_int(x); if (x) { - i = undump_charinfo(f); /* right boundary */ + /*tex right boundary */ + i = undump_charinfo(f); } - i = font_bc(f); while (i < font_ec(f)) { i = undump_charinfo(f); } } -/* moved from pdffont.w */ +/* The \PK\ pixel density value from |texmf.cnf| */ + +int pk_dpi; -@ @c -int pk_dpi; /* PK pixel density value from \.{texmf.cnf} */ +/*tex + + This one looks up the font for a \TFM\ with name |s| loaded at |fs| size and + if found then flushes |s|. + +*/ -@ @c internal_font_number tfm_lookup(char *s, scaled fs) -{ /* looks up for a TFM with name |s| loaded at |fs| size; if found then flushes |s| */ +{ internal_font_number k; if (fs != 0) { for (k = 1; k <= max_font_id(); k++) { @@ -1814,9 +1779,14 @@ internal_font_number tfm_lookup(char *s, scaled fs) return null_font; } -@ @c +/*tex + + This returns the multiple of |font_step(f)| that is nearest to |e|. + +*/ + int fix_expand_value(internal_font_number f, int e) -{ /* return the multiple of |font_step(f)| that is nearest to |e| */ +{ int step; int max_expand; boolean neg; @@ -1842,7 +1812,6 @@ int fix_expand_value(internal_font_number f, int e) return e; } -@ @c void set_expand_params(internal_font_number f, int stretch_limit, int shrink_limit, int font_step) { set_font_step(f, font_step); @@ -1850,19 +1819,20 @@ void set_expand_params(internal_font_number f, int stretch_limit, int shrink_lim set_font_max_stretch(f, stretch_limit); } -@ @c +/*tex + + This reads font expansion spec and load expanded font. + +*/ + void read_expand_font(void) -{ /* read font expansion spec and load expanded font */ +{ int shrink_limit, stretch_limit, font_step; internal_font_number f; - /* read font expansion parameters */ scan_font_ident(); f = cur_val; if (f == null_font) normal_error("font expansion", "invalid font identifier"); - /*if (pdf_font_blink(f) != null_font)*/ - /* normal_error("font expansion",*/ - /* "\\fontexpand cannot be used this way (the base font has been expanded)");*/ scan_optional_equals(); scan_int(); stretch_limit = fix_int(cur_val, 0, 1000); @@ -1882,24 +1852,21 @@ void read_expand_font(void) normal_error("font expansion", "invalid limit(s)"); if (scan_keyword("autoexpand")) { normal_warning("font expansion", "autoexpand not supported"); - /* Scan an optional space */ + /*tex scan an optional space */ get_x_token(); if (cur_cmd != spacer_cmd) back_input(); } if (font_step(f) != 0) { - /* this font has been expanded, ensure the expansion parameters are identical */ + /*tex This font has been expanded, ensure the expansion parameters are identical. */ if (font_step(f) != font_step) normal_error("font expansion","font has been expanded with different expansion step"); - if (((font_max_stretch(f) == 0) && (stretch_limit != 0)) || - ((font_max_stretch(f) > 0) - && (font_max_stretch(f) != stretch_limit))) + ((font_max_stretch(f) > 0) && (font_max_stretch(f) != stretch_limit))) normal_error("font expansion","font has been expanded with different stretch limit"); if (((font_max_shrink(f) == 0) && (shrink_limit != 0)) || - ((font_max_shrink(f) > 0) - && (font_max_shrink(f) != shrink_limit))) + ((font_max_shrink(f) > 0) && (font_max_shrink(f) != shrink_limit))) normal_error("font expansion","font has been expanded with different shrink limit"); } else { if (font_used(f)) @@ -1908,11 +1875,17 @@ void read_expand_font(void) } } -@ @c +/*tex + + Here's an old (sort of obsolete) letterspace-a-font helper. It does so by by + creating a virtual font. + +*/ + void new_letterspaced_font(small_number a) -{ /* letter-space a font by creating a virtual font */ - pointer u; /* user's font identifier */ - str_number t; /* name for the frozen font identifier */ +{ + pointer u; + str_number t; internal_font_number f, k; boolean nolig = false; get_r_token(); @@ -1934,11 +1907,17 @@ void new_letterspaced_font(small_number a) font_id_text(f) = t; } -@ @c +/*tex + + This makes a font copy for further use with font expansion. Again a + traditional font related helper. + +*/ + void make_font_copy(small_number a) -{ /* make a font copy for further use with font expansion */ - pointer u; /* user's font identifier */ - str_number t; /* name for the frozen font identifier */ +{ + pointer u; + str_number t; internal_font_number f, k; get_r_token(); u = cur_cs; @@ -1956,7 +1935,6 @@ void make_font_copy(small_number a) font_id_text(f) = t; } -@ @c void glyph_to_unicode(void) { str_number s1, s2; diff --git a/Build/source/texk/web2c/luatexdir/font/tfmofm.c b/Build/source/texk/web2c/luatexdir/font/tfmofm.c new file mode 100644 index 00000000000..f5d8c2e92f3 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/font/tfmofm.c @@ -0,0 +1,1186 @@ +/* + +Copyright 2006-2012 Taco Hoekwater <taco@@luatex.org> + +This file is part of LuaTeX. + +LuaTeX 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. + +LuaTeX 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU General Public License along +with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +*/ + +#include "ptexlib.h" + +/*tex Here are some macros that help process ligatures and kerns */ + +#define lig_kern_start(f,c) char_remainder(f,c) + +/*tex A value indicating |STOP| in a lig/kern program: */ + +#define stop_flag 128 + +/*tex The op code for a kern step: */ + +#define kern_flag 128 + +#define skip_byte(z) lig_kerns[z].b0 +#define next_char(z) lig_kerns[z].b1 +#define op_byte(z) lig_kerns[z].b2 +#define rem_byte(z) lig_kerns[z].b3 +#define lig_kern_restart(c) (256*op_byte(c)+rem_byte(c)) + + +/*tex + + The information in a \TFM\file appears in a sequence of 8-bit bytes. Since + the number of bytes is always a multiple of 4, we could also regard the file + as a sequence of 32-bit words, but \TeX\ uses the byte interpretation. The + format of \TFM\files was designed by Lyle Ramshaw in 1980. The intent is + to convey a lot of different kinds of information in a compact but useful + form. + + $\Omega$ is capable of reading not only \TFM\files, but also \.{OFM} + files, which can describe fonts with up to 65536 characters and with huge + lig/kern tables. These fonts will often be virtual fonts built up from real + fonts with 256 characters, but $\Omega$ is not aware of this. + + The documentation below describes \TFM\files, with slight additions to + show where \.{OFM} files differ. + + The first 24 bytes (6 words) of a \TFM\file contain twelve 16-bit integers + that give the lengths of the various subsequent portions of the file. These + twelve integers are, in order: + + \starttabulate + \NC \type {lf| \NC length of the entire file, in words \NC \NR + \NC \type {lh| \NC length of the header data, in words \NC \NR + \NC \type {bc| \NC smallest character code in the font \NC \NR + \NC \type {ec| \NC largest character code in the font \NC \NR + \NC \type {nw| \NC number of words in the width table \NC \NR + \NC \type {nh| \NC number of words in the height table \NC \NR + \NC \type {nd| \NC number of words in the depth table \NC \NR + \NC \type {ni| \NC number of words in the italic correction table \NC \NR + \NC \type {nl| \NC number of words in the lig/kern table \NC \NR + \NC \type {nk| \NC number of words in the kern table \NC \NR + \NC \type {ne| \NC number of words in the extensible character table \NC \NR + \NC \type {np| \NC number of font parameter words \NC \NR + \stoptabulate + + They are all nonnegative and less than $2^{15}$. We must have + |bc-1<=ec<=255|, and $|lf=6+lh+(ec-bc+1)+nw+nh+nd+ni+nl+nk+ne+np|$. Note that + a \TFM\font may contain as many as 256 characters (if |bc=0| and + |ec=255|), and as few as 0 characters (if |bc=ec+1|). + + Incidentally, when two or more 8-bit bytes are combined to form an integer of + 16 or more bits, the most significant bytes appear first in the file. This is + called BigEndian order. + + The first 52 bytes (13 words) of an \.{OFM} file contains thirteen 32-bit + integers that give the lengths of the various subsequent portions of the + file. The first word is 0 (future versions of \.{OFM} files could have + different values; what is important is that the first two bytes be 0 to + differentiate \TFM\and \.{OFM} files). The next twelve integers are as + above, all nonegative and less than~$2^{31}$. We must have |bc-1<=ec<=65535|, + and $$\hbox{|lf=13+lh+2*(ec-bc+1)+nw+nh+nd+ni+nl+nk+ne+np|.}$$ Note that an + \.{OFM} font may contain as many as 65536 characters (if |bc=0| and + |ec=65535|), and as few as 0 characters (if |bc=ec+1|). + + The rest of the \TFM\file may be regarded as a sequence of ten data arrays + having the informal specification + + \starttabulate + \NC \type {header} \NC \type {[0..lh-1]} \NC \type {stuff} \NC \NR + \NC \type {char\_info} \NC \type {[bc..ec]} \NC \type {char_info_word} \NC \NR + \NC \type {width} \NC \type {[0..nw-1]} \NC \type {fix_word} \NC \NR + \NC \type {height} \NC \type {[0..nh-1]} \NC \type {fix_word} \NC \NR + \NC \type {depth} \NC \type {[0..nd-1]} \NC \type {fix_word} \NC \NR + \NC \type {italic} \NC \type {[0..ni-1]} \NC \type {fix_word} \NC \NR + \NC \type {lig\_kern} \NC \type {[0..nl-1]} \NC \type {lig_kern_command} \NC \NR + \NC \type {kern} \NC \type {[0..nk-1]} \NC \type {fix_word} \NC \NR + \NC \type {exten} \NC \type {[0..ne-1]} \NC \type {extensible_recipe} \NC \NR + \NC \type {param} \NC \type {[1..np]} \NC \type {fix_word} \NC \NR + \stoptabulate + + The most important data type used here is a |@!fix_word|, which is a 32-bit + representation of a binary fraction. A |fix_word| is a signed quantity, with + the two's complement of the entire word used to represent negation. Of the 32 + bits in a |fix_word|, exactly 12 are to the left of the binary point; thus, + the largest |fix_word| value is $2048-2^{-20}$, and the smallest is $-2048$. + We will see below, however, that all but two of the |fix_word| values must + lie between $-16$ and $+16$. + + The first data array is a block of header information, which contains general + facts about the font. The header must contain at least two words, |header[0]| + and |header[1]|, whose meaning is explained below. Additional header + information of use to other software routines might also be included, but + \TeX82 does not need to know about such details. For example, 16 more words + of header information are in use at the Xerox Palo Alto Research Center; the + first ten specify the character coding scheme used (e.g., `\.{XEROX text}' or + `\.{TeX math symbols}'), the next five give the font identifier (e.g., + `\.{HELVETICA}' or `\.{CMSY}'), and the last gives the ``face byte.'' The + program that converts \.{DVI} files to Xerox printing format gets this + information by looking at the \TFM\file, which it needs to read anyway + because of other information that is not explicitly repeated in + \.{DVI}~format. + + \startitemize + + \startitem + |header[0]| is a 32-bit check sum that \TeX\ will copy into the + \.{DVI} output file. Later on when the \.{DVI} file is printed, + possibly on another computer, the actual font that gets used is + supposed to have a check sum that agrees with the one in the \TFM\ + file used by \TeX. In this way, users will be warned about potential + incompatibilities. (However, if the check sum is zero in either the + font file or the \TFM\file, no check is made.) The actual relation + between this check sum and the rest of the \TFM\file is not + important; the check sum is simply an identification number with the + property that incompatible fonts almost always have distinct check + sums. + \stopitem + + \startitem + |header[1]| is a |fix_word| containing the design size of the font, + in units of \TeX\ points. This number must be at least 1.0; it is + fairly arbitrary, but usually the design size is 10.0 for a ``10 + point'' font, i.e., a font that was designed to look best at a + 10-point size, whatever that really means. When a \TeX\ user asks for + a font `\.{at} $\delta$ \.{pt}', the effect is to override the design + size and replace it by $\delta$, and to multiply the $x$ and~$y$ + coordinates of the points in the font image by a factor of $\delta$ + divided by the design size. {\sl All other dimensions in the\/ + \TFM\file are |fix_word|\kern-1pt\ numbers in design-size units}, + with the exception of |param[1]| (which denotes the slant ratio). + Thus, for example, the value of |param[6]|, which defines the \.{em} + unit, is often the |fix_word| value $2^{20}=1.0$, since many fonts + have a design size equal to one em. The other dimensions must be less + than 16 design-size units in absolute value; thus, |header[1]| and + |param[1]| are the only |fix_word| entries in the whole \TFM\file + whose first byte might be something besides 0 or 255. + \stopitem + + \stopitemize + + Next comes the |char_info| array, which contains one |@!char_info_word| per + character. Each word in this part of a \TFM\file contains six fields + packed into four bytes as follows. + + \startitemize + \startitem + first byte: |width_index| (8 bits) + \stopitem + \startitem + second byte: |height_index| (4 bits) times 16, plus |depth_index| + (4~bits) + \stopitem + \startitem + third byte: |italic_index| (6 bits) times 4, plus |tag| (2~bits) + \stopitem + \startitem + fourth byte: |remainder| (8 bits) + \stopitem + \stopitemize + + The actual width of a character is \\{width}|[width_index]|, in design-size + units; this is a device for compressing information, since many characters + have the same width. Since it is quite common for many characters to have the + same height, depth, or italic correction, the \TFM\format imposes a limit + of 16 different heights, 16 different depths, and 64 different italic + corrections. + + For \.{OFM} files, two words (eight bytes) are used. The arrangement is as + follows. + + \startitemize + \startitem + first and second bytes: |width_index| (16 bits) + \stopitem + \startitem third byte: |height_index| (8 bits) + \stopitem + \startitem + fourth byte: |depth_index| (8~bits) + \stopitem + \startitem + fifth and sixth bytes: |italic_index| (14 bits) times 4, plus |tag| + (2~bits) + \startitem + seventh and eighth bytes: |remainder| (16 bits) + \stopitem + \stopitemize + + Therefore the \.{OFM} format imposes a limit of 256 different heights, 256 + different depths, and 16384 different italic corrections. + + The italic correction of a character has two different uses. (a)~In ordinary + text, the italic correction is added to the width only if the \TeX\ user + specifies `\.{\\/}' after the character. (b)~In math formulas, the italic + correction is always added to the width, except with respect to the + positioning of subscripts. + + Incidentally, the relation $\\{width}[0]=\\{height}[0]=\\{depth}[0]= + \\{italic}[0]=0$ should always hold, so that an index of zero implies a value + of zero. The |width_index| should never be zero unless the character does not + exist in the font, since a character is valid if and only if it lies between + |bc| and |ec| and has a nonzero |width_index|. + + \TeX\ checks the information of a \TFM\file for validity as the file is + being read in, so that no further checks will be needed when typesetting is + going on. The somewhat tedious subroutine that does this is called + |read_font_info|. It has four parameters: the user font identifier~|u|, the + file name and area strings |nom| and |aire|, and the ``at'' size~|s|. If + |s|~is negative, it's the negative of a scale factor to be applied to the + design size; |s=-1000| is the normal case. Otherwise |s| will be substituted + for the design size; in this case, |s| must be positive and less than + $2048\rm\,pt$ (i.e., it must be less than $2^{27}$ when considered as an + integer). + + The subroutine opens and closes a global file variable called |tfm_file|. It + returns the value of the internal font number that was just loaded. If an + error is detected, an error message is issued and no font information is + stored; |null_font| is returned in this case. + + The |tag| field in a |char_info_word| has four values that explain how to + interpret the |remainder| field. + + \startitemize + \startitem + |tag=0| (|no_tag|) means that |remainder| is unused. + \stopitem + \startitem + |tag=1| (|lig_tag|) means that this character has a ligature/kerning + program starting at position |remainder| in the |lig_kern| array + \stopitem + \startitem + |tag=2| (|list_tag|) means that this character is part of a chain of + characters of ascending sizes, and not the largest in the chain. The + |remainder| field gives the character code of the next larger + character + \stopitem + \startitem + |tag=3| (|ext_tag|) means that this character code represents an + extensible character, i.e., a character that is built up of smaller + pieces so that it can be made arbitrarily large. The pieces are + specified in |exten[remainder]| + \stopitem + \stopitemize + + Characters with |tag=2| and |tag=3| are treated as characters with |tag=0| + unless they are used in special circumstances in math formulas. For example, + the \.{\\sum} operation looks for a |list_tag|, and the \.{\\left} operation + looks for both |list_tag| and |ext_tag|. + + The |lig_kern| array contains instructions in a simple programming language + that explains what to do for special letter pairs. Each word in this array, + in a \TFM\file, is a |@!lig_kern_command| of four bytes. + + \startitemize + \startitem + first byte: |skip_byte|, indicates that this is the final program + step if the byte is 128 or more, otherwise the next step is obtained + by skipping this number of intervening steps + \stopitem + \startitem + second byte: |next_char|, if |next_char| follows the current + character, then perform the operation and stop, otherwise + continue + \stopitem + \startitem + third byte: |op_byte|, indicates a ligature step if less than~128, a + kern step otherwise + \stopitem + \startitem + fourth byte: |remainder| + \stopitem + \stopitemize + + In an \.{OFM} file, eight bytes are used, two bytes for each field. + + In a kern step, an additional space equal to |kern[256 * (op_byte-128) + + remainder]| is inserted between the current character and |next_char|. This + amount is often negative, so that the characters are brought closer together + by kerning; but it might be positive. + + There are eight kinds of ligature steps, having |op_byte| codes $4a+2b+c$ + where $0\le a\le b+c$ and $0\le b,c\le1$. The character whose code is + |remainder| is inserted between the current character and |next_char|; then + the current character is deleted if $b=0$, and |next_char| is deleted if + $c=0$; then we pass over $a$~characters to reach the next current character + (which may have a ligature/kerning program of its own). + + If the very first instruction of the |lig_kern| array has |skip_byte=255|, + the |next_char| byte is the so-called right boundary character of this font; + the value of |next_char| need not lie between |bc| and~|ec|. If the very last + instruction of the |lig_kern| array has |skip_byte=255|, there is a special + ligature/kerning program for a left boundary character, beginning at location + |256*op_byte+remainder|. The interpretation is that \TeX\ puts implicit + boundary characters before and after each consecutive string of characters + from the same font. These implicit characters do not appear in the output, + but they can affect ligatures and kerning. + + If the very first instruction of a character's |lig_kern| program has + |skip_byte>128|, the program actually begins in location + |256*op_byte+remainder|. This feature allows access to large |lig_kern| + arrays, because the first instruction must otherwise appear in a location + |<=255| in a \TFM\file, |<=65535| in an \.{OFM} file. + + Any instruction with |skip_byte>128| in the |lig_kern| array must satisfy the + condition $$\hbox{|256*op_byte+remainder<nl|.}$$ If such an instruction is + encountered during normal program execution, it denotes an unconditional + halt; no ligature or kerning command is performed. + + Extensible characters are specified by an |@!extensible_recipe|, which + consists of four bytes in a \TFM\file, called |@!top|, |@!mid|, |@!bot|, + and |@!rep| (in this order). In an \.{OFM} file, each field takes two bytes, + for eight in total. These bytes are the character codes of individual pieces + used to build up a large symbol. If |top|, |mid|, or |bot| are zero, they are + not present in the built-up result. For example, an extensible vertical line + is like an extensible bracket, except that the top and bottom pieces are + missing. + + Let $T$, $M$, $B$, and $R$ denote the respective pieces, or an empty box if + the piece isn't present. Then the extensible characters have the form + $TR^kMR^kB$ from top to bottom, for some |k>=0|, unless $M$ is absent; in the + latter case we can have $TR^kB$ for both even and odd values of~|k|. The + width of the extensible character is the width of $R$; and the + height-plus-depth is the sum of the individual height-plus-depths of the + components used, since the pieces are butted together in a vertical list. + + The final portion of a \TFM\file is the |param| array, which is another + sequence of |fix_word| values. + + \startitemize + + \startitem + |param[1]=slant| is the amount of italic slant, which is used to help + position accents. For example, |slant=.25| means that when you go up one + unit, you also go .25 units to the right. The |slant| is a pure number; + it's the only |fix_word| other than the design size itself that is not + scaled by the design size. + \stopitem + + \startitem + |param[2]=space| is the normal spacing between words in text. Note that + character |" "| in the font need not have anything to do with blank + spaces. + \stopitem + + \startitem + |param[3]=space_stretch| is the amount of glue stretching between words. + \stopitem + + \startitem + |param[4]=space_shrink| is the amount of glue shrinking between words. + \stopitem + + \startitem + |param[5]=x_height| is the size of one ex in the font; it is also the + height of letters for which accents don't have to be raised or lowered. + \stopitem + + \startitem + |param[6]=quad| is the size of one em in the font. + \stopitem + + \startitem + |param[7]=extra_space| is the amount added to |param[2]| at the ends of + sentences. + \stopitem + + + If fewer than seven parameters are present, \TeX\ sets the missing parameters + to zero. Fonts used for math symbols are required to have additional + parameter information, which is explained later. + + + There are programs called \.{TFtoPL} and \.{PLtoTF} that convert between the + \TFM\format and a symbolic property-list format that can be easily edited. + These programs contain extensive diagnostic information, so \TeX\ does not + have to bother giving precise details about why it rejects a particular + \TFM\file. + +*/ + +#define tfm_abort { \ + font_tables[f]->_font_name = NULL; \ + font_tables[f]->_font_area = NULL; \ + xfree(tfm_buffer); xfree(kerns); \ + xfree(widths); \ + xfree(heights); \ + xfree(depths); \ + xfree(italics); \ + xfree(extens); \ + xfree(lig_kerns); \ + xfree(xligs); \ + xfree(xkerns); \ + return 0; \ +} + +#define tfm_success { \ + xfree(tfm_buffer); \ + xfree(kerns); \ + xfree(widths); \ + xfree(heights); \ + xfree(depths); \ + xfree(italics); \ + xfree(extens); \ + xfree(lig_kerns); \ + xfree(xligs); \ + xfree(xkerns); \ + return 1; \ +} + +static int open_tfm_file(const char *nom, unsigned char **tfm_buf, int *tfm_siz) +{ + /*tex Was the callback successful? */ + boolean res; + /*tex Was |tfm_file| successfully opened? */ + boolean opened; + int callback_id; + FILE *tfm_file; + char *fname = luatex_find_file(nom, find_font_file_callback); + if (!fname) + return -1; + callback_id = callback_defined(read_font_file_callback); + if (callback_id > 0) { + res = run_callback(callback_id, "S->bSd", fname, &opened, tfm_buf, tfm_siz); + if (res && opened && (*tfm_siz > 0)) { + return 1; + } + if (!opened) + return -1; + } else { + if (luatex_open_input(&(tfm_file), fname, kpse_ofm_format, FOPEN_RBIN_MODE, true)) { + res = read_tfm_file(tfm_file, tfm_buf, tfm_siz); + close_file(tfm_file); + if (res) { + return 1; + } + } else { + return -1; + } + } + return 0; +} + +/*tex + + Note: A malformed \TFM\file might be shorter than it claims to be; thus + |eof(tfm_file)| might be true when |read_font_info| refers to |tfm_file^| or + when it says |get(tfm_file)|. If such circumstances cause system error + messages, you will have to defeat them somehow, for example by defining |fget| + to be `\ignorespaces|begin get(tfm_file);| |if eof(tfm_file) then abort; + end|'. + +*/ + +#define fget tfm_byte++ +#define fbyte tfm_buffer[tfm_byte] + +#define read_sixteen(a) { \ + a=tfm_buffer[tfm_byte++]; \ + if (a>127) { tfm_abort; } \ + a=(a*256)+tfm_buffer[tfm_byte]; \ +} + +#define read_sixteen_unsigned(a) { \ + a=tfm_buffer[tfm_byte++]; \ + a=(a*256)+tfm_buffer[tfm_byte]; \ +} + +#define read_thirtytwo(a) { \ + a=tfm_buffer[++tfm_byte]; \ + if (a>127) { tfm_abort; } \ + a=(a*256)+tfm_buffer[++tfm_byte]; \ + a=(a*256)+tfm_buffer[++tfm_byte]; \ + a=(a*256)+tfm_buffer[++tfm_byte]; \ +} + +#define store_four_bytes(z) { \ + a=tfm_buffer[++tfm_byte]; \ + a=(a*256)+tfm_buffer[++tfm_byte]; \ + a=(a*256)+tfm_buffer[++tfm_byte]; \ + a=(a*256)+tfm_buffer[++tfm_byte]; \ + z = a; \ +} + +#define store_char_info(z) { \ + if (font_level!=-1) { \ + fget; read_sixteen_unsigned(a); \ + ci._width_index=a; \ + fget; read_sixteen_unsigned(b); \ + ci._height_index=b>>8; \ + ci._depth_index=b%256; \ + fget; read_sixteen_unsigned(c); \ + ci._italic_index=c>>8; \ + ci._tag=(unsigned char)(c%4); \ + fget; read_sixteen_unsigned(d); \ + ci._remainder=d; \ + } else { \ + a=tfm_buffer[++tfm_byte]; \ + ci._width_index=a; \ + b=tfm_buffer[++tfm_byte]; \ + ci._height_index=b>>4; \ + ci._depth_index=b%16; \ + c=tfm_buffer[++tfm_byte]; \ + ci._italic_index=c>>2; \ + ci._tag=(unsigned char)(c%4); \ + d=tfm_buffer[++tfm_byte]; \ + ci._remainder=d; \ + } \ +} + +#define read_four_quarters(q) { \ + if (font_level!=-1) { \ + fget; read_sixteen_unsigned(a); q.b0=(quarterword)a; \ + fget; read_sixteen_unsigned(b); q.b1=(quarterword)b; \ + fget; read_sixteen_unsigned(c); q.b2=(quarterword)c; \ + fget; read_sixteen_unsigned(d); q.b3=(quarterword)d; \ + } else { \ + a=tfm_buffer[++tfm_byte]; q.b0=(quarterword)a; \ + b=tfm_buffer[++tfm_byte]; q.b1=(quarterword)b; \ + c=tfm_buffer[++tfm_byte]; q.b2=(quarterword)c; \ + d=tfm_buffer[++tfm_byte]; q.b3=(quarterword)d; \ + } \ +} + +#define check_byte_range(z) { if ((z<bc)||(z>ec)) tfm_abort ; } + +/* + + A |fix_word| whose four bytes are $(a,b,c,d)$ from left to right represents + the number $$x=\left\{\vcenter{\halign{$#$,\hfil\qquad&if $#$\hfil\cr + b\cdot2^{-4}+c\cdot2^{-12}+d\cdot2^{-20}&a=0;\cr + -16+b\cdot2^{-4}+c\cdot2^{-12}+d\cdot2^{-20}&a=255.\cr}}\right.$$ (No other + choices of |a| are allowed, since the magnitude of a number in design-size + units must be less than 16.) We want to multiply this quantity by the + integer~|z|, which is known to be less than $2^{27}$. If $|z|<2^{23}$, the + individual multiplications $b\cdot z$, $c\cdot z$, $d\cdot z$ cannot + overflow; otherwise we will divide |z| by 2, 4, 8, or 16, to obtain a + multiplier less than $2^{23}$, and we can compensate for this later. If |z| + has thereby been replaced by $|z|^\prime=|z|/2^e$, let $\beta=2^{4-e}$; we + shall compute $$\lfloor (b + c \cdot2^{-8} + d \cdot2^{-16}) \, z^\prime / + \beta \rfloor$$ if $a=0$, or the same quantity minus $\alpha=2^{4+e}z^\prime$ + if $a=255$. This calculation must be done exactly, in order to guarantee + portability of \TeX\ between computers. + +*/ + +#define store_scaled(zz) { \ + fget; \ + a = fbyte; \ + fget; \ + b = fbyte; \ + fget; \ + c = fbyte; \ + fget; \ + d = fbyte; \ + sw = (((((d*z)>>8)+(c*z))>>8)+(b*z)) / beta; \ + if (a == 0) { \ + zz = sw; \ + } else if (a == 255) { \ + zz = sw-alpha; \ + } else { \ + tfm_abort; \ + } \ +} + +scaled store_scaled_f(scaled sq, scaled z_in) +{ + eight_bits a, b, c, d; + scaled sw; + /*tex Here beta: runs from 1 upto 16 */ + static int alpha, beta; + static scaled z, z_prev = 0; + /*tex Replace |z| by $|z|^\prime$ and compute $\alpha,\beta$ */ + if (z_in != z_prev || z_prev == 0) { + z = z_prev = z_in; + alpha = 16; + while (z >= 0x800000) { + z /= 2; + alpha += alpha; + } + beta = 256 / alpha; + alpha *= z; + }; + if (sq >= 0) { + d = (eight_bits) (sq % 256); + sq = sq / 256; + c = (eight_bits) (sq % 256); + sq = sq / 256; + b = (eight_bits) (sq % 256); + sq = sq / 256; + a = (eight_bits) (sq % 256); + } else { + sq = (sq + 1073741824) + 1073741824; + d = (eight_bits) (sq % 256); + sq = sq / 256; + c = (eight_bits) (sq % 256); + sq = sq / 256; + b = (eight_bits) (sq % 256); + sq = sq / 256; + a = (eight_bits) ((sq + 128) % 256); + } + if (beta==0) + normal_error("vf", "vf scaling"); + sw = (((((d * z) >> 8) + (c * z)) >> 8) + (b * z)) / beta; + if (a == 0) + return sw; + else if (a == 255) + return (sw - alpha); + else + normal_error("vf", "vf scaling"); + return sw; +} + +#define check_existence(z) { \ + check_byte_range(z); \ + if (!char_exists(f,z)) { \ + tfm_abort; \ + } \ +} + +typedef struct tfmcharacterinfo { + int _kern_index; + int _lig_index; + int _width_index; + int _height_index; + int _depth_index; + int _italic_index; + int _remainder; + unsigned char _tag; +} tfmcharacterinfo; + +int read_tfm_info(internal_font_number f, const char *cnom, scaled s) +{ + /*tex index into |font_info| */ + int k; + /*tex sizes of subfiles */ + halfword lf, lh, bc, ec, nw, nh, nd, ni, nl, nk, ne, np, slh; + scaled *widths, *heights, *depths, *italics, *kerns; + halfword font_dir; + /*tex byte variables */ + int a, b, c=0, d=0; + /*tex counter */ + int i; + int font_level, header_length; + int ncw, nlw, neew; + tfmcharacterinfo ci; + charinfo *co; + four_quarters qw; + four_quarters *lig_kerns, *extens; + /*tex accumulators */ + scaled sw; + /*tex left boundary start location, or infinity */ + int bch_label; + /*tex 0..too_big_char; right boundary character, or |too_big_char| */ + int bchar; + int first_two; + /*tex the design size or the ``at'' size */ + scaled z; + int alpha; + /*tex 1..16 */ + char beta; + /*tex aux. for ligkern processing */ + int *xligs, *xkerns; + liginfo *cligs; + kerninfo *ckerns; + int fligs, fkerns; + char *tmpnam; + /*tex index into |tfm_buffer| */ + int tfm_byte = 0; + /*tex saved index into |tfm_buffer| */ + int saved_tfm_byte = 0; + /*tex byte buffer for tfm files */ + unsigned char *tfm_buffer = NULL; + /*tex total size of the tfm file */ + int tfm_size = 0; + int tmp; + widths = NULL; + heights = NULL; + depths = NULL; + italics = NULL; + kerns = NULL; + lig_kerns = NULL; + extens = NULL; + xkerns = NULL; + ckerns = NULL; + xligs = NULL; + cligs = NULL; + font_dir = 0; + memset(&ci, 0, sizeof(tfmcharacterinfo)); + if (open_tfm_file(cnom, &tfm_buffer, &tfm_size) != 1) + tfm_abort; + /*tex When |cnom| is an absolute filename |xbasename| fixes that. */ + tmpnam = strdup(xbasename(cnom)); + if (strcmp(tmpnam + strlen(tmpnam) - 4, ".tfm") == 0 || strcmp(tmpnam + strlen(tmpnam) - 4, ".ofm") == 0) { + *(tmpnam + strlen(tmpnam) - 4) = 0; + } + set_font_name(f, tmpnam); + set_font_area(f, NULL); + /*tex Read the \TFM\ size fields. */ + ncw = 0; + read_sixteen(first_two); + if (first_two != 0) { + font_level = -1; + lf = first_two; + fget; + read_sixteen(lh); + fget; + read_sixteen(bc); + fget; + read_sixteen(ec); + if ((bc > ec + 1) || (ec > 255)) + tfm_abort; + if (bc > 255) { + /*tex |bc=256| and |ec=255| */ + bc = 1; + ec = 0; + }; + fget; + read_sixteen(nw); + fget; + read_sixteen(nh); + fget; + read_sixteen(nd); + fget; + read_sixteen(ni); + fget; + read_sixteen(nl); + fget; + read_sixteen(nk); + fget; + read_sixteen(ne); + fget; + read_sixteen(np); + header_length = 6; + ncw = (ec - bc + 1); + nlw = nl; + neew = ne; + } else { + fget; + read_sixteen(font_level); + if (font_level != 0) + tfm_abort; + read_thirtytwo(lf); + read_thirtytwo(lh); + read_thirtytwo(bc); + read_thirtytwo(ec); + if ((bc > ec + 1) || (ec > 65535)) + tfm_abort; + if (bc > 65535) { + /*tex |bc=65536| and |ec=65535| */ + bc = 1; + ec = 0; + }; + read_thirtytwo(nw); + read_thirtytwo(nh); + read_thirtytwo(nd); + read_thirtytwo(ni); + read_thirtytwo(nl); + read_thirtytwo(nk); + read_thirtytwo(ne); + read_thirtytwo(np); + /*tex Some junk: */ + read_thirtytwo(font_dir); + nlw = 2 * nl; + neew = 2 * ne; + header_length = 14; + ncw = 2 * (ec - bc + 1); + }; + if (lf != + (header_length + lh + ncw + nw + nh + nd + ni + nlw + nk + neew + np)) + tfm_abort; + if ((nw == 0) || (nh == 0) || (nd == 0) || (ni == 0)) + tfm_abort; + /*tex + We check to see that the \TFM\ file doesn't end prematurely; but no + error message is given for files having more than |lf| words. + */ + if (lf * 4 > tfm_size) + tfm_abort; + /*tex Use size fields to allocate font information. */ + set_font_natural_dir(f, font_dir); + set_font_bc(f, bc); + set_font_ec(f, ec); + /*tex Read the arrays first. */ + widths = xmalloc((unsigned) ((unsigned) nw * sizeof(scaled))); + heights = xmalloc((unsigned) ((unsigned) nh * sizeof(scaled))); + depths = xmalloc((unsigned) ((unsigned) nd * sizeof(scaled))); + italics = xmalloc((unsigned) ((unsigned) ni * sizeof(scaled))); + extens = xmalloc((unsigned) ((unsigned) ne * sizeof(four_quarters))); + lig_kerns = xmalloc((unsigned) ((unsigned) nl * sizeof(four_quarters))); + kerns = xmalloc((unsigned) ((unsigned) nk * sizeof(scaled))); + /* + Read the \TFM\ header. Only the first two words of the header are needed + by \TeX82. + */ + slh = lh; + if (lh < 2) + tfm_abort; + store_four_bytes(tmp); + font_checksum(f) = (unsigned) tmp; + fget; + /*tex This rejects a negative design size. */ + read_sixteen(z); + fget; + z = z * 256 + fbyte; + fget; + z = (z * 16) + (fbyte >> 4); + if (z < unity) + tfm_abort; + while (lh > 2) { + fget; + fget; + fget; + fget; + /*tex Ignore the rest of the header. */ + lh--; + }; + /*tex Read the arrays before the character info. */ + set_font_dsize(f, z); + if (s != -1000) { + z = (s >= 0 ? s : xn_over_d(z, -s, 1000)); + } + set_font_size(f, z); + if (np > 7) { + set_font_params(f, np); + } + saved_tfm_byte = tfm_byte; + tfm_byte = (header_length + slh + ncw) * 4 - 1; + /*tex Replace |z| by $|z|^\prime$ and compute $\alpha,\beta$ */ + alpha = 16; + while (z >= 040000000) { + z = z >> 1; + alpha = alpha + alpha; + }; + beta = (char) (256 / alpha); + /*tex |beta| cannot be zero. */ + if (beta==0) + normal_error("vf", "vf reading"); + alpha = alpha * z; + /*tex Read box dimensions. */ + for (k = 0; k < nw; k++) { + store_scaled(sw); + widths[k] = sw; + } + /*tex |width[0]| must be zero */ + if (widths[0] != 0) + tfm_abort; + for (k = 0; k < nh; k++) { + store_scaled(sw); + heights[k] = sw; + } + /*tex |height[0]| must be zero */ + if (heights[0] != 0) + tfm_abort; + for (k = 0; k < nd; k++) { + store_scaled(sw); + depths[k] = sw; + } + /*tex |depth[0]| must be zero */ + if (depths[0] != 0) + tfm_abort; + for (k = 0; k < ni; k++) { + store_scaled(sw); + italics[k] = sw; + } + /*tex |italic[0]| must be zero */ + if (italics[0] != 0) + tfm_abort; + /*tex Read ligature and kern programs */ + bch_label = nl; + bchar = 65536; + if (nl > 0) { + for (k = 0; k < nl; k++) { + read_four_quarters(qw); + lig_kerns[k] = qw; + if (a > 128) { + if (256 * c + d >= nl) + tfm_abort; + if (a == 255 && k == 0) + bchar = b; + } else { + if (c < 128) { + /*tex Do nothing. */ + } else if (256 * (c - 128) + d >= nk) { + /*tex Check kern. */ + tfm_abort; + } + if ((a < 128) && (k - 0 + a + 1 >= nl)) + tfm_abort; + }; + }; + if (a == 255) + bch_label = 256 * c + d; + }; + /*tex The actual kerns */ + for (k = 0; k < nk; k++) { + store_scaled(sw); + kerns[k] = sw; + } + /*tex Read extensible character recipes */ + for (k = 0; k < ne; k++) { + read_four_quarters(qw); + extens[k] = qw; + } + /*tex Read font parameters. */ + if (np > 7) { + set_font_params(f, np); + } + for (k = 1; k <= np; k++) { + if (k == 1) { + /*tex The |slant| parameter is a pure number. */ + fget; + sw = fbyte; + if (sw > 127) + sw = sw - 256; + fget; + sw = sw * 256 + fbyte; + fget; + sw = sw * 256 + fbyte; + fget; + sw = (sw * 16) + (fbyte >> 4); + set_font_param(f, k, sw); + } else { + store_scaled(font_param(f, k)); + } + } + tfm_byte = saved_tfm_byte; + /*tex Fix up the left boundary character. */ + fligs = 0; + fkerns = 0; + if (bch_label != nl) { + k = bch_label; + while (1) { + if (skip_byte(k) <= stop_flag) { + if (op_byte(k) >= kern_flag) { + fkerns++; + } else { + fligs++; + } + } + if (skip_byte(k) == 0) { + k++; + } else { + if (skip_byte(k) >= stop_flag) + break; + k += skip_byte(k) + 1; + } + } + } + if (fkerns > 0 || fligs > 0) { + if (fligs > 0) + cligs = xcalloc((unsigned) (fligs + 1), sizeof(liginfo)); + if (fkerns > 0) + ckerns = xcalloc((unsigned) (fkerns + 1), sizeof(kerninfo)); + fligs = 0; + fkerns = 0; + k = bch_label; + while (1) { + if (skip_byte(k) <= stop_flag) { + if (op_byte(k) >= kern_flag) { + set_kern_item(ckerns[fkerns], next_char(k), kerns[256 * (op_byte(k) - 128) + rem_byte(k)]); + fkerns++; + } else { + set_ligature_item(cligs[fligs], (char) (op_byte(k) * 2 + 1), next_char(k), rem_byte(k)); + fligs++; + } + } + if (skip_byte(k) == 0) { + k++; + } else { + if (skip_byte(k) >= stop_flag) + break; + k += skip_byte(k) + 1; + } + } + if (fkerns > 0 || fligs > 0) { + co = get_charinfo(f, left_boundarychar); + if (fkerns > 0) { + set_kern_item(ckerns[fkerns], end_kern, 0); + fkerns++; + set_charinfo_kerns(co, ckerns); + } + if (fligs > 0) { + set_ligature_item(cligs[fligs], 0, end_ligature, 0); + fligs++; + set_charinfo_ligatures(co, cligs); + } + set_charinfo_remainder(co, 0); + } + } + /*tex Read character data. */ + for (k = bc; k <= ec; k++) { + store_char_info(k); + if (ci._width_index == 0) + continue; + if (ci._width_index >= nw || ci._height_index >= nh || + ci._depth_index >= nd || ci._italic_index >= ni) + tfm_abort; + d = ci._remainder; + switch (ci._tag) { + case lig_tag: + if (d >= nl) + tfm_abort; + break; + case ext_tag: + if (d >= ne) + tfm_abort; + break; + case list_tag: + /*tex + + We want to make sure that there is no cycle of characters linked + together by |list_tag| entries, since such a cycle would get + \TEX\ into an endless loop. If such a cycle exists, the routine + here detects it when processing the largest character code in the + cycle. + + */ + check_byte_range(d); + while (d < k) { + /* |current_character == k| */ + if (char_tag(f, d) != list_tag) { + /*tex Not a cycle. */ + goto NOT_FOUND; + } + /*tex Goto the next character on the list. */ + d = char_remainder(f, d); + }; + if (d == k) { + /*tex Yes, there's a cycle! */ + tfm_abort; + } + NOT_FOUND: + break; + } + /*tex Put it in the actual font. */ + co = get_charinfo(f, k); + set_charinfo_index(co, k); + set_charinfo_tag(co, ci._tag); + if (ci._tag == ext_tag) { + /*tex top, bot, mid, rep */ + set_charinfo_extensible(co, + extens[ci._remainder].b0, + extens[ci._remainder].b2, + extens[ci._remainder].b1, + extens[ci._remainder].b3); + set_charinfo_remainder(co, 0); + } else { + set_charinfo_remainder(co, ci._remainder); + } + set_charinfo_width(co, widths[ci._width_index]); + set_charinfo_height(co, heights[ci._height_index]); + set_charinfo_depth(co, depths[ci._depth_index]); + set_charinfo_italic(co, italics[ci._italic_index]); + }; + /*tex We now know the number of ligatures and kerns. */ + xligs = xcalloc((unsigned) (ec + 1), sizeof(int)); + xkerns = xcalloc((unsigned) (ec + 1), sizeof(int)); + for (i = bc; i <= ec; i++) { + if (char_tag(f, i) == lig_tag) { + k = lig_kern_start(f, i); + if (skip_byte(k) > stop_flag) + k = lig_kern_restart(k); + /*tex Now k is the start index. */ + while (1) { + if (skip_byte(k) <= stop_flag) { + if (op_byte(k) >= kern_flag) { + xkerns[i]++; + if (next_char(k) == bchar) + xkerns[i]++; + } else { + xligs[i]++; + if (next_char(k) == bchar) + xligs[i]++; + } + } + if (skip_byte(k) == 0) { + k++; + } else { + if (skip_byte(k) >= stop_flag) + break; + k += skip_byte(k) + 1; + } + } + } + } + cligs = NULL; + ckerns = NULL; + for (i = bc; i <= ec; i++) { + fligs = 0; + fkerns = 0; + if (char_tag(f, i) == lig_tag) { + k = lig_kern_start(f, i); + if (skip_byte(k) > stop_flag) + k = lig_kern_restart(k); + /*tex Now k is the start index. */ + if (xligs[i] > 0) + cligs = xcalloc((unsigned) (xligs[i] + 1), sizeof(liginfo)); + if (xkerns[i] > 0) + ckerns = xcalloc((unsigned) (xkerns[i] + 1), sizeof(kerninfo)); + while (1) { + if (skip_byte(k) <= stop_flag) { + if (op_byte(k) >= kern_flag) { + if (next_char(k) == bchar) { + set_kern_item(ckerns[fkerns], right_boundarychar, kerns[256 * (op_byte(k) - 128) + rem_byte(k)]); + fkerns++; + } + set_kern_item(ckerns[fkerns], next_char(k), kerns[256 * (op_byte(k) - 128) + rem_byte(k)]); + fkerns++; + } else { /* lig */ + if (next_char(k) == bchar) { + set_ligature_item(cligs[fligs], (char) (op_byte(k) * 2 + 1), right_boundarychar, rem_byte(k)); + fligs++; + } + set_ligature_item(cligs[fligs], (char) (op_byte(k) * 2 + 1), next_char(k), rem_byte(k)); + fligs++; + } + } + if (skip_byte(k) == 0) { + k++; + } else { + if (skip_byte(k) >= stop_flag) + break; + k += skip_byte(k) + 1; + } + } + if (fkerns > 0 || fligs > 0) { + co = get_charinfo(f, i); + if (fkerns > 0) { + set_kern_item(ckerns[fkerns], end_kern, 0); + fkerns++; + set_charinfo_kerns(co, ckerns); + } + if (fligs > 0) { + set_ligature_item(cligs[fligs], 0, end_ligature, 0); + fligs++; + set_charinfo_ligatures(co, cligs); + } + set_charinfo_remainder(co, 0); + } + } + } + /*tex + + Now it's time to wrap it up, we have checked all the necessary things + about the \TFM\file, and all we need to do is put the finishing + touches on the data for the new font. + + */ + if (bchar != 65536) { + co = copy_charinfo(char_info(f, bchar)); + set_right_boundary(f, co); + } + tfm_success; +} diff --git a/Build/source/texk/web2c/luatexdir/font/tfmofm.w b/Build/source/texk/web2c/luatexdir/font/tfmofm.w deleted file mode 100644 index 6eeccdda214..00000000000 --- a/Build/source/texk/web2c/luatexdir/font/tfmofm.w +++ /dev/null @@ -1,1119 +0,0 @@ -% tfmofm.w -% -% Copyright 2006-2012 Taco Hoekwater <taco@@luatex.org> -% -% This file is part of LuaTeX. -% -% LuaTeX 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. -% -% LuaTeX 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 Lesser General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License along -% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. - -@ @c - - -#include "ptexlib.h" - -@ Here are some macros that help process ligatures and kerns -@c -#define lig_kern_start(f,c) char_remainder(f,c) -#define stop_flag 128 /* value indicating `\.{STOP}' in a lig/kern program */ -#define kern_flag 128 /* op code for a kern step */ - -#define skip_byte(z) lig_kerns[z].b0 -#define next_char(z) lig_kerns[z].b1 -#define op_byte(z) lig_kerns[z].b2 -#define rem_byte(z) lig_kerns[z].b3 -#define lig_kern_restart(c) (256*op_byte(c)+rem_byte(c)) - - -@ -The information in a \.{TFM} file appears in a sequence of 8-bit bytes. -Since the number of bytes is always a multiple of 4, we could -also regard the file as a sequence of 32-bit words, but \TeX\ uses the -byte interpretation. The format of \.{TFM} files was designed by -Lyle Ramshaw in 1980. The intent is to convey a lot of different kinds -@^Ramshaw, Lyle Harold@> -of information in a compact but useful form. - -$\Omega$ is capable of reading not only \.{TFM} files, but also -\.{OFM} files, which can describe fonts with up to 65536 characters -and with huge lig/kern tables. These fonts will often be virtual -fonts built up from real fonts with 256 characters, but $\Omega$ -is not aware of this. - -The documentation below describes \.{TFM} files, with slight additions -to show where \.{OFM} files differ. - -@ -The first 24 bytes (6 words) of a \.{TFM} file contain twelve 16-bit -integers that give the lengths of the various subsequent portions -of the file. These twelve integers are, in order: -$$\vbox{\halign{\hfil#&$\null=\null$#\hfil\cr -|lf|&length of the entire file, in words;\cr -|lh|&length of the header data, in words;\cr -|bc|&smallest character code in the font;\cr -|ec|&largest character code in the font;\cr -|nw|&number of words in the width table;\cr -|nh|&number of words in the height table;\cr -|nd|&number of words in the depth table;\cr -|ni|&number of words in the italic correction table;\cr -|nl|&number of words in the lig/kern table;\cr -|nk|&number of words in the kern table;\cr -|ne|&number of words in the extensible character table;\cr -|np|&number of font parameter words.\cr}}$$ -They are all nonnegative and less than $2^{15}$. We must have |bc-1<=ec<=255|, -and -$$\hbox{|lf=6+lh+(ec-bc+1)+nw+nh+nd+ni+nl+nk+ne+np|.}$$ -Note that a \.{TFM} font may contain as many as 256 characters -(if |bc=0| and |ec=255|), and as few as 0 characters (if |bc=ec+1|). - -Incidentally, when two or more 8-bit bytes are combined to form an integer of -16 or more bits, the most significant bytes appear first in the file. -This is called BigEndian order. -@!@^BigEndian order@> - -The first 52 bytes (13 words) of an \.{OFM} file contains thirteen -32-bit integers that give the lengths of the various subsequent -portions of the file. The first word is 0 (future versions of -\.{OFM} files could have different values; what is important is that -the first two bytes be 0 to differentiate \.{TFM} and \.{OFM} files). -The next twelve integers are as above, all nonegative and less -than~$2^{31}$. We must have |bc-1<=ec<=65535|, and -$$\hbox{|lf=13+lh+2*(ec-bc+1)+nw+nh+nd+ni+nl+nk+ne+np|.}$$ -Note that an \.{OFM} font may contain as many as 65536 characters -(if |bc=0| and |ec=65535|), and as few as 0 characters (if |bc=ec+1|). - -The rest of the \.{TFM} file may be regarded as a sequence of ten data -arrays having the informal specification -$$\def\arr$[#1]#2${\&{array} $[#1]$ \&{of} #2} -\def\doarr\PB#1{\arr#1} -\vbox{\halign{\hfil\\{#}&$\,:\,$\doarr#\hfil\cr -header&|[0..lh-1]stuff|\cr -char\_info&|[bc..ec]char_info_word|\cr -width&|[0..nw-1]fix_word|\cr -height&|[0..nh-1]fix_word|\cr -depth&|[0..nd-1]fix_word|\cr -italic&|[0..ni-1]fix_word|\cr -lig\_kern&|[0..nl-1]lig_kern_command|\cr -kern&|[0..nk-1]fix_word|\cr -exten&|[0..ne-1]extensible_recipe|\cr -param&\omit |[1..np]fix_word|\cr}}$$ -The most important data type used here is a |@!fix_word|, which is -a 32-bit representation of a binary fraction. A |fix_word| is a signed -quantity, with the two's complement of the entire word used to represent -negation. Of the 32 bits in a |fix_word|, exactly 12 are to the left of the -binary point; thus, the largest |fix_word| value is $2048-2^{-20}$, and -the smallest is $-2048$. We will see below, however, that all but two of -the |fix_word| values must lie between $-16$ and $+16$. - -The first data array is a block of header information, which contains -general facts about the font. The header must contain at least two words, -|header[0]| and |header[1]|, whose meaning is explained below. -Additional header information of use to other software routines might -also be included, but \TeX82 does not need to know about such details. -For example, 16 more words of header information are in use at the Xerox -Palo Alto Research Center; the first ten specify the character coding -scheme used (e.g., `\.{XEROX text}' or `\.{TeX math symbols}'), the next five -give the font identifier (e.g., `\.{HELVETICA}' or `\.{CMSY}'), and the -last gives the ``face byte.'' The program that converts \.{DVI} files -to Xerox printing format gets this information by looking at the \.{TFM} -file, which it needs to read anyway because of other information that -is not explicitly repeated in \.{DVI}~format. - -\yskip\hang|header[0]| is a 32-bit check sum that \TeX\ will copy into -the \.{DVI} output file. Later on when the \.{DVI} file is printed, -possibly on another computer, the actual font that gets used is supposed -to have a check sum that agrees with the one in the \.{TFM} file used by -\TeX. In this way, users will be warned about potential incompatibilities. -(However, if the check sum is zero in either the font file or the \.{TFM} -file, no check is made.) The actual relation between this check sum and -the rest of the \.{TFM} file is not important; the check sum is simply an -identification number with the property that incompatible fonts almost -always have distinct check sums. -@^check sum@> - -\yskip\hang|header[1]| is a |fix_word| containing the design size of -the font, in units of \TeX\ points. This number must be at least 1.0; it is -fairly arbitrary, but usually the design size is 10.0 for a ``10 point'' -font, i.e., a font that was designed to look best at a 10-point size, -whatever that really means. When a \TeX\ user asks for a font -`\.{at} $\delta$ \.{pt}', the effect is to override the design size -and replace it by $\delta$, and to multiply the $x$ and~$y$ coordinates -of the points in the font image by a factor of $\delta$ divided by the -design size. {\sl All other dimensions in the\/ \.{TFM} file are -|fix_word|\kern-1pt\ numbers in design-size units}, with the exception of -|param[1]| (which denotes the slant ratio). Thus, for example, the value -of |param[6]|, which defines the \.{em} unit, is often the |fix_word| value -$2^{20}=1.0$, since many fonts have a design size equal to one em. -The other dimensions must be less than 16 design-size units in absolute -value; thus, |header[1]| and |param[1]| are the only |fix_word| -entries in the whole \.{TFM} file whose first byte might be something -besides 0 or 255. - -Next comes the |char_info| array, which contains one |@!char_info_word| -per character. Each word in this part of a \.{TFM} file contains six fields -packed into four bytes as follows. - -\yskip\hang first byte: |@!width_index| (8 bits)\par -\hang second byte: |@!height_index| (4 bits) times 16, plus |@!depth_index| - (4~bits)\par -\hang third byte: |@!italic_index| (6 bits) times 4, plus |@!tag| - (2~bits)\par -\hang fourth byte: |@!remainder| (8 bits)\par -\yskip\noindent -The actual width of a character is \\{width}|[width_index]|, in design-size -units; this is a device for compressing information, since many characters -have the same width. Since it is quite common for many characters -to have the same height, depth, or italic correction, the \.{TFM} format -imposes a limit of 16 different heights, 16 different depths, and -64 different italic corrections. - -For \.{OFM} files, two words (eight bytes) are used. -The arrangement is as follows. - -\yskip\hang first and second bytes: |@!width_index| (16 bits)\par -\hang third byte: |@!height_index| (8 bits)\par -\hang fourth byte: |@!depth_index| (8~bits)\par -\hang fifth and sixth bytes: -|@!italic_index| (14 bits) times 4, plus |@!tag| (2~bits)\par -\hang seventh and eighth bytes: |@!remainder| (16 bits)\par -\yskip\noindent -Therefore the \.{OFM} format imposes a limit of 256 different heights, -256 different depths, and 16384 different italic corrections. - -@!@^italic correction@> -The italic correction of a character has two different uses. -(a)~In ordinary text, the italic correction is added to the width only if -the \TeX\ user specifies `\.{\\/}' after the character. -(b)~In math formulas, the italic correction is always added to the width, -except with respect to the positioning of subscripts. - -Incidentally, the relation $\\{width}[0]=\\{height}[0]=\\{depth}[0]= -\\{italic}[0]=0$ should always hold, so that an index of zero implies a -value of zero. The |width_index| should never be zero unless the -character does not exist in the font, since a character is valid if and -only if it lies between |bc| and |ec| and has a nonzero |width_index|. - - -@ \TeX\ checks the information of a \.{TFM} file for validity as the -file is being read in, so that no further checks will be needed when -typesetting is going on. The somewhat tedious subroutine that does this -is called |read_font_info|. It has four parameters: the user font -identifier~|u|, the file name and area strings |nom| and |aire|, and the -``at'' size~|s|. If |s|~is negative, it's the negative of a scale factor -to be applied to the design size; |s=-1000| is the normal case. -Otherwise |s| will be substituted for the design size; in this -case, |s| must be positive and less than $2048\rm\,pt$ -(i.e., it must be less than $2^{27}$ when considered as an integer). - -The subroutine opens and closes a global file variable called |tfm_file|. -It returns the value of the internal font number that was just loaded. -If an error is detected, an error message is issued and no font -information is stored; |null_font| is returned in this case. - -@ -The |tag| field in a |char_info_word| has four values that explain how to -interpret the |remainder| field. - -\yskip\hang|tag=0| (|no_tag|) means that |remainder| is unused.\par -\hang|tag=1| (|lig_tag|) means that this character has a ligature/kerning -program starting at position |remainder| in the |lig_kern| array.\par -\hang|tag=2| (|list_tag|) means that this character is part of a chain of -characters of ascending sizes, and not the largest in the chain. The -|remainder| field gives the character code of the next larger character.\par -\hang|tag=3| (|ext_tag|) means that this character code represents an -extensible character, i.e., a character that is built up of smaller pieces -so that it can be made arbitrarily large. The pieces are specified in -|@!exten[remainder]|.\par -\yskip\noindent -Characters with |tag=2| and |tag=3| are treated as characters with |tag=0| -unless they are used in special circumstances in math formulas. For example, -the \.{\\sum} operation looks for a |list_tag|, and the \.{\\left} -operation looks for both |list_tag| and |ext_tag|. - - -@ The |lig_kern| array contains instructions in a simple programming language -that explains what to do for special letter pairs. Each word in this array, -in a \.{TFM} file, is a |@!lig_kern_command| of four bytes. - -\yskip\hang first byte: |skip_byte|, indicates that this is the final program - step if the byte is 128 or more, otherwise the next step is obtained by - skipping this number of intervening steps.\par -\hang second byte: |next_char|, ``if |next_char| follows the current character, - then perform the operation and stop, otherwise continue.''\par -\hang third byte: |op_byte|, indicates a ligature step if less than~128, - a kern step otherwise.\par -\hang fourth byte: |remainder|.\par -\yskip\noindent -In an \.{OFM} file, eight bytes are used, two bytes for each field. - -In a kern step, an -additional space equal to |kern[256*(op_byte-128)+remainder]| is inserted -between the current character and |next_char|. This amount is -often negative, so that the characters are brought closer together -by kerning; but it might be positive. - -There are eight kinds of ligature steps, having |op_byte| codes $4a+2b+c$ where -$0\le a\le b+c$ and $0\le b,c\le1$. The character whose code is -|remainder| is inserted between the current character and |next_char|; -then the current character is deleted if $b=0$, and |next_char| is -deleted if $c=0$; then we pass over $a$~characters to reach the next -current character (which may have a ligature/kerning program of its own). - -If the very first instruction of the |lig_kern| array has |skip_byte=255|, -the |next_char| byte is the so-called right boundary character of this font; -the value of |next_char| need not lie between |bc| and~|ec|. -If the very last instruction of the |lig_kern| array has |skip_byte=255|, -there is a special ligature/kerning program for a left boundary character, -beginning at location |256*op_byte+remainder|. -The interpretation is that \TeX\ puts implicit boundary characters -before and after each consecutive string of characters from the same font. -These implicit characters do not appear in the output, but they can affect -ligatures and kerning. - -If the very first instruction of a character's |lig_kern| program has -|skip_byte>128|, the program actually begins in location -|256*op_byte+remainder|. This feature allows access to large |lig_kern| -arrays, because the first instruction must otherwise -appear in a location |<=255| in a \.{TFM} file, |<=65535| in an \.{OFM} file. - -Any instruction with |skip_byte>128| in the |lig_kern| array must satisfy -the condition -$$\hbox{|256*op_byte+remainder<nl|.}$$ -If such an instruction is encountered during -normal program execution, it denotes an unconditional halt; no ligature -or kerning command is performed. - - -@ Extensible characters are specified by an |@!extensible_recipe|, which -consists of four bytes in a \.{TFM} file, -called |@!top|, |@!mid|, |@!bot|, and |@!rep| (in this order). -In an \.{OFM} file, each field takes two bytes, for eight in total. -These bytes are the character codes of individual pieces used to -build up a large symbol. If |top|, |mid|, or |bot| are zero, they are not -present in the built-up result. For example, an extensible vertical line is -like an extensible bracket, except that the top and bottom pieces are missing. - -Let $T$, $M$, $B$, and $R$ denote the respective pieces, or an empty box -if the piece isn't present. Then the extensible characters have the form -$TR^kMR^kB$ from top to bottom, for some |k>=0|, unless $M$ is absent; -in the latter case we can have $TR^kB$ for both even and odd values of~|k|. -The width of the extensible character is the width of $R$; and the -height-plus-depth is the sum of the individual height-plus-depths of the -components used, since the pieces are butted together in a vertical list. - - -@ -The final portion of a \.{TFM} file is the |param| array, which is another -sequence of |fix_word| values. - -\yskip\hang|param[1]=slant| is the amount of italic slant, which is used -to help position accents. For example, |slant=.25| means that when you go -up one unit, you also go .25 units to the right. The |slant| is a pure -number; it's the only |fix_word| other than the design size itself that is -not scaled by the design size. - -\hang|param[2]=space| is the normal spacing between words in text. -Note that character |" "| in the font need not have anything to do with -blank spaces. - -\hang|param[3]=space_stretch| is the amount of glue stretching between words. - -\hang|param[4]=space_shrink| is the amount of glue shrinking between words. - -\hang|param[5]=x_height| is the size of one ex in the font; it is also -the height of letters for which accents don't have to be raised or lowered. - -\hang|param[6]=quad| is the size of one em in the font. - -\hang|param[7]=extra_space| is the amount added to |param[2]| at the -ends of sentences. - -\yskip\noindent -If fewer than seven parameters are present, \TeX\ sets the missing parameters -to zero. Fonts used for math symbols are required to have -additional parameter information, which is explained later. - - -@ - There are programs called \.{TFtoPL} and \.{PLtoTF} that convert - between the \.{TFM} format and a symbolic property-list format - that can be easily edited. These programs contain extensive - diagnostic information, so \TeX\ does not have to bother giving - precise details about why it rejects a particular \.{TFM} file. - -@c -#define tfm_abort { font_tables[f]->_font_name = NULL; \ - font_tables[f]->_font_area = NULL; \ - xfree(tfm_buffer); xfree(kerns); \ - xfree(widths); xfree(heights); xfree(depths); \ - xfree(italics); xfree(extens); xfree(lig_kerns); \ - xfree(xligs); xfree(xkerns); \ - return 0; } - -#define tfm_success { xfree(tfm_buffer); xfree(kerns); \ - xfree(widths); xfree(heights); xfree(depths); \ - xfree(italics); xfree(extens); xfree(lig_kerns); \ - xfree(xligs); xfree(xkerns); return 1; } - -@ @c -static int open_tfm_file(const char *nom, unsigned char **tfm_buf, int *tfm_siz) -{ - boolean res; /* was the callback successful? */ - boolean opened; /* was |tfm_file| successfully opened? */ - int callback_id; - FILE *tfm_file; - char *fname = luatex_find_file(nom, find_font_file_callback); - if (!fname) - return -1; - callback_id = callback_defined(read_font_file_callback); - if (callback_id > 0) { - res = - run_callback(callback_id, "S->bSd", fname, &opened, tfm_buf, - tfm_siz); - if (res && opened && (*tfm_siz > 0)) { - return 1; - } - if (!opened) - return -1; - } else { - if (luatex_open_input - (&(tfm_file), fname, kpse_ofm_format, FOPEN_RBIN_MODE, true)) { - res = read_tfm_file(tfm_file, tfm_buf, tfm_siz); - close_file(tfm_file); - if (res) { - return 1; - } - } else { - return -1; - } - } - return 0; -} - - -@ - Note: A malformed \.{TFM} file might be shorter than it claims to be; - thus |eof(tfm_file)| might be true when |read_font_info| refers to - |tfm_file^| or when it says |get(tfm_file)|. If such circumstances - cause system error messages, you will have to defeat them somehow, - for example by defining |fget| to be `\ignorespaces|begin get(tfm_file);| - |if eof(tfm_file) then abort; end|\unskip'. - @^system dependencies@> -@c - -#define fget tfm_byte++ -#define fbyte tfm_buffer[tfm_byte] - -#define read_sixteen(a) \ - { a=tfm_buffer[tfm_byte++]; \ - if (a>127) { tfm_abort; } \ - a=(a*256)+tfm_buffer[tfm_byte]; } - -#define read_sixteen_unsigned(a) \ - { a=tfm_buffer[tfm_byte++]; \ - a=(a*256)+tfm_buffer[tfm_byte]; } - -#define read_thirtytwo(a) \ - { a=tfm_buffer[++tfm_byte]; \ - if (a>127) { tfm_abort; } \ - a=(a*256)+tfm_buffer[++tfm_byte]; \ - a=(a*256)+tfm_buffer[++tfm_byte]; \ - a=(a*256)+tfm_buffer[++tfm_byte]; } - -#define store_four_bytes(z) \ - { a=tfm_buffer[++tfm_byte]; \ - a=(a*256)+tfm_buffer[++tfm_byte]; \ - a=(a*256)+tfm_buffer[++tfm_byte]; \ - a=(a*256)+tfm_buffer[++tfm_byte]; \ - z = a; } - -#define store_char_info(z) \ - { if (font_level!=-1) { \ - fget; read_sixteen_unsigned(a); \ - ci._width_index=a; \ - fget; read_sixteen_unsigned(b); \ - ci._height_index=b>>8; \ - ci._depth_index=b%256; \ - fget; read_sixteen_unsigned(c); \ - ci._italic_index=c>>8; \ - ci._tag=(unsigned char)(c%4); \ - fget; read_sixteen_unsigned(d); \ - ci._remainder=d; \ - } else { \ - a=tfm_buffer[++tfm_byte]; \ - ci._width_index=a; \ - b=tfm_buffer[++tfm_byte]; \ - ci._height_index=b>>4; \ - ci._depth_index=b%16; \ - c=tfm_buffer[++tfm_byte]; \ - ci._italic_index=c>>2; \ - ci._tag=(unsigned char)(c%4); \ - d=tfm_buffer[++tfm_byte]; \ - ci._remainder=d; \ - } } - -#define read_four_quarters(q) \ - { if (font_level!=-1) { \ - fget; read_sixteen_unsigned(a); q.b0=(quarterword)a; \ - fget; read_sixteen_unsigned(b); q.b1=(quarterword)b; \ - fget; read_sixteen_unsigned(c); q.b2=(quarterword)c; \ - fget; read_sixteen_unsigned(d); q.b3=(quarterword)d; \ - } else { \ - a=tfm_buffer[++tfm_byte]; q.b0=(quarterword)a; \ - b=tfm_buffer[++tfm_byte]; q.b1=(quarterword)b; \ - c=tfm_buffer[++tfm_byte]; q.b2=(quarterword)c; \ - d=tfm_buffer[++tfm_byte]; q.b3=(quarterword)d; \ - } } - -#define check_byte_range(z) { if ((z<bc)||(z>ec)) tfm_abort ; } - - -@ A |fix_word| whose four bytes are $(a,b,c,d)$ from left to right represents - the number - $$x=\left\{\vcenter{\halign{$#$,\hfil\qquad&if $#$\hfil\cr - b\cdot2^{-4}+c\cdot2^{-12}+d\cdot2^{-20}&a=0;\cr - -16+b\cdot2^{-4}+c\cdot2^{-12}+d\cdot2^{-20}&a=255.\cr}}\right.$$ - (No other choices of |a| are allowed, since the magnitude of a number in - design-size units must be less than 16.) We want to multiply this - quantity by the integer~|z|, which is known to be less than $2^{27}$. - If $|z|<2^{23}$, the individual multiplications $b\cdot z$, - $c\cdot z$, $d\cdot z$ cannot overflow; otherwise we will divide |z| by 2, - 4, 8, or 16, to obtain a multiplier less than $2^{23}$, and we can - compensate for this later. If |z| has thereby been replaced by - $|z|^\prime=|z|/2^e$, let $\beta=2^{4-e}$; we shall compute - $$\lfloor(b+c\cdot2^{-8}+d\cdot2^{-16})\,z^\prime/\beta\rfloor$$ - if $a=0$, or the same quantity minus $\alpha=2^{4+e}z^\prime$ if $a=255$. - This calculation must be done exactly, in order to guarantee portability - of \TeX\ between computers. - -@c -#define store_scaled(zz) \ - { fget; a=fbyte; fget; b=fbyte; \ - fget; c=fbyte; fget; d=fbyte; \ - sw=(((((d*z)>>8)+(c*z))>>8)+(b*z)) / beta; \ - if (a==0) { zz=sw; } else if (a==255) { zz=sw-alpha; } else tfm_abort; \ - } - -scaled store_scaled_f(scaled sq, scaled z_in) -{ - eight_bits a, b, c, d; - scaled sw; - static int alpha, beta; /* beta:1..16 */ - static scaled z, z_prev = 0; - /* Replace |z| by $|z|^\prime$ and compute $\alpha,\beta$ */ - if (z_in != z_prev || z_prev == 0) { - z = z_prev = z_in; - alpha = 16; - while (z >= 0x800000) { - z /= 2; - alpha += alpha; - } - beta = 256 / alpha; - alpha *= z; - }; - if (sq >= 0) { - d = (eight_bits) (sq % 256); - sq = sq / 256; - c = (eight_bits) (sq % 256); - sq = sq / 256; - b = (eight_bits) (sq % 256); - sq = sq / 256; - a = (eight_bits) (sq % 256); - } else { - sq = (sq + 1073741824) + 1073741824; /* braces for optimizing compiler */ - d = (eight_bits) (sq % 256); - sq = sq / 256; - c = (eight_bits) (sq % 256); - sq = sq / 256; - b = (eight_bits) (sq % 256); - sq = sq / 256; - a = (eight_bits) ((sq + 128) % 256); - } - if (beta==0) - normal_error("vf", "vf scaling"); - sw = (((((d * z) >> 8) + (c * z)) >> 8) + (b * z)) / beta; - if (a == 0) - return sw; - else if (a == 255) - return (sw - alpha); - else - normal_error("vf", "vf scaling"); - return sw; /* not reached, just to make the compiler happy */ -} - -@ @c -#define check_existence(z) \ - { check_byte_range(z); \ - if (!char_exists(f,z)) tfm_abort; \ - } - -typedef struct tfmcharacterinfo { - int _kern_index; - int _lig_index; - int _width_index; - int _height_index; - int _depth_index; - int _italic_index; - int _remainder; - unsigned char _tag; -} tfmcharacterinfo; - -@ @c -int read_tfm_info(internal_font_number f, const char *cnom, scaled s) -{ - int k; /* index into |font_info| */ - halfword lf, lh, bc, ec, nw, nh, nd, ni, nl, nk, ne, np, slh; /* sizes of subfiles */ - scaled *widths, *heights, *depths, *italics, *kerns; - halfword font_dir; - int a, b, c=0, d=0; /* byte variables */ - int i; /* counter */ - int font_level, header_length; - int ncw, nlw, neew; - tfmcharacterinfo ci; - charinfo *co; - four_quarters qw; - four_quarters *lig_kerns, *extens; - scaled sw; /* accumulators */ - int bch_label; /* left boundary start location, or infinity */ - int bchar; /* |:0..too_big_char;| *//* right boundary character, or |too_big_char| */ - int first_two; - scaled z; /* the design size or the ``at'' size */ - int alpha; - char beta; /* :1..16 */ - int *xligs, *xkerns; /* aux. for ligkern processing */ - liginfo *cligs; - kerninfo *ckerns; - int fligs, fkerns; - char *tmpnam; - int tfm_byte = 0; /* index into |tfm_buffer| */ - int saved_tfm_byte = 0; /* saved index into |tfm_buffer| */ - unsigned char *tfm_buffer = NULL; /* byte buffer for tfm files */ - int tfm_size = 0; /* total size of the tfm file */ - int tmp; - - widths = NULL; - heights = NULL; - depths = NULL; - italics = NULL; - kerns = NULL; - lig_kerns = NULL; - extens = NULL; - xkerns = NULL; - ckerns = NULL; - xligs = NULL; - cligs = NULL; - - font_dir = 0; - - memset(&ci, 0, sizeof(tfmcharacterinfo)); - - if (open_tfm_file(cnom, &tfm_buffer, &tfm_size) != 1) - tfm_abort; - - /* cnom can be an absolute filename, xbasename() fixes that. */ - - tmpnam = strdup(xbasename(cnom)); - if (strcmp(tmpnam + strlen(tmpnam) - 4, ".tfm") == 0 || strcmp(tmpnam + strlen(tmpnam) - 4, ".ofm") == 0) { - *(tmpnam + strlen(tmpnam) - 4) = 0; - } - set_font_name(f, tmpnam); - set_font_area(f, NULL); - - /* Read the {\.{TFM}} size fields */ - ncw = 0; - read_sixteen(first_two); - if (first_two != 0) { - font_level = -1; - lf = first_two; - fget; - read_sixteen(lh); - fget; - read_sixteen(bc); - fget; - read_sixteen(ec); - if ((bc > ec + 1) || (ec > 255)) - tfm_abort; - if (bc > 255) { /* |bc=256| and |ec=255| */ - bc = 1; - ec = 0; - }; - fget; - read_sixteen(nw); - fget; - read_sixteen(nh); - fget; - read_sixteen(nd); - fget; - read_sixteen(ni); - fget; - read_sixteen(nl); - fget; - read_sixteen(nk); - fget; - read_sixteen(ne); - fget; - read_sixteen(np); - header_length = 6; - ncw = (ec - bc + 1); - nlw = nl; - neew = ne; - } else { - fget; - read_sixteen(font_level); - if (font_level != 0) - tfm_abort; - read_thirtytwo(lf); - read_thirtytwo(lh); - read_thirtytwo(bc); - read_thirtytwo(ec); - if ((bc > ec + 1) || (ec > 65535)) - tfm_abort; - if (bc > 65535) { /* |bc=65536| and |ec=65535| */ - bc = 1; - ec = 0; - }; - read_thirtytwo(nw); - read_thirtytwo(nh); - read_thirtytwo(nd); - read_thirtytwo(ni); - read_thirtytwo(nl); - read_thirtytwo(nk); - read_thirtytwo(ne); - read_thirtytwo(np); - read_thirtytwo(font_dir); /* junk */ - nlw = 2 * nl; - neew = 2 * ne; - header_length = 14; - ncw = 2 * (ec - bc + 1); - }; - if (lf != - (header_length + lh + ncw + nw + nh + nd + ni + nlw + nk + neew + np)) - tfm_abort; - if ((nw == 0) || (nh == 0) || (nd == 0) || (ni == 0)) - tfm_abort; - - /* - We check to see that the \.{TFM} file doesn't end prematurely; but - no error message is given for files having more than |lf| words. - */ - if (lf * 4 > tfm_size) - tfm_abort; - - /* Use size fields to allocate font information */ - - set_font_natural_dir(f, font_dir); - set_font_bc(f, bc); - set_font_ec(f, ec); - - /* read the arrays first */ - widths = xmalloc((unsigned) ((unsigned) nw * sizeof(scaled))); - heights = xmalloc((unsigned) ((unsigned) nh * sizeof(scaled))); - depths = xmalloc((unsigned) ((unsigned) nd * sizeof(scaled))); - italics = xmalloc((unsigned) ((unsigned) ni * sizeof(scaled))); - extens = xmalloc((unsigned) ((unsigned) ne * sizeof(four_quarters))); - lig_kerns = xmalloc((unsigned) ((unsigned) nl * sizeof(four_quarters))); - kerns = xmalloc((unsigned) ((unsigned) nk * sizeof(scaled))); - - /* Read the {\.{TFM}} header */ - - /* Only the first two words of the header are needed by \TeX82. */ - slh = lh; - if (lh < 2) - tfm_abort; - store_four_bytes(tmp); - font_checksum(f) = (unsigned) tmp; - fget; - read_sixteen(z); /* this rejects a negative design size */ - fget; - z = z * 256 + fbyte; - fget; - z = (z * 16) + (fbyte >> 4); - if (z < unity) - tfm_abort; - while (lh > 2) { - fget; - fget; - fget; - fget; - lh--; /* ignore the rest of the header */ - }; - - /* read the arrays before the character info */ - - set_font_dsize(f, z); - if (s != -1000) { - z = (s >= 0 ? s : xn_over_d(z, -s, 1000)); - } - set_font_size(f, z); - - if (np > 7) - set_font_params(f, np); - - saved_tfm_byte = tfm_byte; - tfm_byte = (header_length + slh + ncw) * 4 - 1; - - /* Replace |z| by $|z|^\prime$ and compute $\alpha,\beta$ */ - - alpha = 16; - while (z >= 040000000) { - z = z >> 1; - alpha = alpha + alpha; - }; - beta = (char) (256 / alpha); - - /* beta cannot be zero */ - if (beta==0) - normal_error("vf", "vf reading"); - alpha = alpha * z; - - /* Read box dimensions */ - - for (k = 0; k < nw; k++) { - store_scaled(sw); - widths[k] = sw; - } - if (widths[0] != 0) /* \\{width}[0] must be zero */ - tfm_abort; - for (k = 0; k < nh; k++) { - store_scaled(sw); - heights[k] = sw; - } - if (heights[0] != 0) - tfm_abort; /* \\{height}[0] must be zero */ - for (k = 0; k < nd; k++) { - store_scaled(sw); - depths[k] = sw; - } - if (depths[0] != 0) - tfm_abort; /* \\{depth}[0] must be zero */ - for (k = 0; k < ni; k++) { - store_scaled(sw); - italics[k] = sw; - } - if (italics[0] != 0) - tfm_abort; /* \\{italic}[0] must be zero */ - - - /* Read ligature/kern program */ - - bch_label = nl; /* infinity */ - bchar = 65536; - if (nl > 0) { - for (k = 0; k < nl; k++) { - read_four_quarters(qw); - lig_kerns[k] = qw; - if (a > 128) { - if (256 * c + d >= nl) - tfm_abort; - if (a == 255 && k == 0) - bchar = b; - } else { -#if 0 - if (b!=bchar) check_existence(b); -#endif - if (c < 128) { -#if 0 - check_existence(d); /* check ligature */ -#endif - } else if (256 * (c - 128) + d >= nk) { - tfm_abort; /* check kern */ - } - if ((a < 128) && (k - 0 + a + 1 >= nl)) - tfm_abort; - }; - }; - if (a == 255) - bch_label = 256 * c + d; - }; - - /* the actual kerns */ - for (k = 0; k < nk; k++) { - store_scaled(sw); - kerns[k] = sw; - } - - /* Read extensible character recipes */ - for (k = 0; k < ne; k++) { - read_four_quarters(qw); - extens[k] = qw; - } - - /* Read font parameters */ - - if (np > 7) { - set_font_params(f, np); - } - for (k = 1; k <= np; k++) { - if (k == 1) { /* the |slant| parameter is a pure number */ - fget; - sw = fbyte; - if (sw > 127) - sw = sw - 256; - fget; - sw = sw * 256 + fbyte; - fget; - sw = sw * 256 + fbyte; - fget; - sw = (sw * 16) + (fbyte >> 4); - set_font_param(f, k, sw); - } else { - store_scaled(font_param(f, k)); - } - } - - tfm_byte = saved_tfm_byte; - - /* fix up the left boundary character */ - fligs = 0; - fkerns = 0; - if (bch_label != nl) { - k = bch_label; -#if 0 - if (skip_byte(k) > stop_flag) - k = lig_kern_restart(k); -#endif - while (1) { - if (skip_byte(k) <= stop_flag) { - if (op_byte(k) >= kern_flag) { /* kern */ - fkerns++; - } else { /* lig */ - fligs++; - } - } - if (skip_byte(k) == 0) { - k++; - } else { - if (skip_byte(k) >= stop_flag) - break; - k += skip_byte(k) + 1; - } - } - } - if (fkerns > 0 || fligs > 0) { - if (fligs > 0) - cligs = xcalloc((unsigned) (fligs + 1), sizeof(liginfo)); - if (fkerns > 0) - ckerns = xcalloc((unsigned) (fkerns + 1), sizeof(kerninfo)); - fligs = 0; - fkerns = 0; - k = bch_label; -#if 0 - if (skip_byte(k) > stop_flag) - k = lig_kern_restart(k); -#endif - while (1) { - if (skip_byte(k) <= stop_flag) { - if (op_byte(k) >= kern_flag) { /* kern */ - set_kern_item(ckerns[fkerns], next_char(k), - kerns[256 * (op_byte(k) - 128) + - rem_byte(k)]); - fkerns++; - } else { /* lig */ - set_ligature_item(cligs[fligs], (char) (op_byte(k) * 2 + 1), - next_char(k), rem_byte(k)); - fligs++; - } - } - if (skip_byte(k) == 0) { - k++; - } else { - if (skip_byte(k) >= stop_flag) - break; - k += skip_byte(k) + 1; - } - } - if (fkerns > 0 || fligs > 0) { - co = get_charinfo(f, left_boundarychar); - if (fkerns > 0) { - set_kern_item(ckerns[fkerns], end_kern, 0); - fkerns++; - set_charinfo_kerns(co, ckerns); - } - if (fligs > 0) { - set_ligature_item(cligs[fligs], 0, end_ligature, 0); - fligs++; - set_charinfo_ligatures(co, cligs); - } - set_charinfo_remainder(co, 0); - } - } - - /* Read character data */ - for (k = bc; k <= ec; k++) { - store_char_info(k); - if (ci._width_index == 0) - continue; - if (ci._width_index >= nw || ci._height_index >= nh || - ci._depth_index >= nd || ci._italic_index >= ni) - tfm_abort; - d = ci._remainder; - switch (ci._tag) { - case lig_tag: - if (d >= nl) - tfm_abort; - break; - case ext_tag: - if (d >= ne) - tfm_abort; - break; - case list_tag: - /* We want to make sure that there is no cycle of characters linked together - by |list_tag| entries, since such a cycle would get \TeX\ into an endless - loop. If such a cycle exists, the routine here detects it when processing - the largest character code in the cycle. - */ - check_byte_range(d); - while (d < k) { /* |current_character == k| */ - if (char_tag(f, d) != list_tag) - goto NOT_FOUND; /* not a cycle */ - d = char_remainder(f, d); /* next character on the list */ - }; - if (d == k) - tfm_abort; /* yes, there's a cycle */ - NOT_FOUND: - break; - } - /* put it in the actual font */ - co = get_charinfo(f, k); - set_charinfo_index(co, k); - set_charinfo_tag(co, ci._tag); - if (ci._tag == ext_tag) { - set_charinfo_extensible(co, extens[ci._remainder].b0, /* top */ - extens[ci._remainder].b2, /* bot */ - extens[ci._remainder].b1, /* mid */ - extens[ci._remainder].b3); /* rep */ - set_charinfo_remainder(co, 0); - } else { - set_charinfo_remainder(co, ci._remainder); - } - set_charinfo_width(co, widths[ci._width_index]); - set_charinfo_height(co, heights[ci._height_index]); - set_charinfo_depth(co, depths[ci._depth_index]); - set_charinfo_italic(co, italics[ci._italic_index]); - }; - - /* first pass: count ligs and kerns */ - - xligs = xcalloc((unsigned) (ec + 1), sizeof(int)); - xkerns = xcalloc((unsigned) (ec + 1), sizeof(int)); - - for (i = bc; i <= ec; i++) { - if (char_tag(f, i) == lig_tag) { - k = lig_kern_start(f, i); - if (skip_byte(k) > stop_flag) - k = lig_kern_restart(k); - /* now k is the start index */ - while (1) { - if (skip_byte(k) <= stop_flag) { - if (op_byte(k) >= kern_flag) { /* kern */ - xkerns[i]++; - if (next_char(k) == bchar) - xkerns[i]++; - } else { /* lig */ - xligs[i]++; - if (next_char(k) == bchar) - xligs[i]++; - } - } - if (skip_byte(k) == 0) { - k++; - } else { - if (skip_byte(k) >= stop_flag) - break; - k += skip_byte(k) + 1; - } - } - } - } - - cligs = NULL; - ckerns = NULL; - - for (i = bc; i <= ec; i++) { - fligs = 0; - fkerns = 0; - if (char_tag(f, i) == lig_tag) { - k = lig_kern_start(f, i); - if (skip_byte(k) > stop_flag) - k = lig_kern_restart(k); - /* now k is the start index */ - if (xligs[i] > 0) - cligs = xcalloc((unsigned) (xligs[i] + 1), sizeof(liginfo)); - if (xkerns[i] > 0) - ckerns = xcalloc((unsigned) (xkerns[i] + 1), sizeof(kerninfo)); - while (1) { - if (skip_byte(k) <= stop_flag) { - if (op_byte(k) >= kern_flag) { /* kern */ - if (next_char(k) == bchar) { - set_kern_item(ckerns[fkerns], right_boundarychar, - kerns[256 * (op_byte(k) - 128) + - rem_byte(k)]); - fkerns++; - } - set_kern_item(ckerns[fkerns], next_char(k), - kerns[256 * (op_byte(k) - 128) + - rem_byte(k)]); - fkerns++; - } else { /* lig */ - if (next_char(k) == bchar) { - set_ligature_item(cligs[fligs], - (char) (op_byte(k) * 2 + 1), - right_boundarychar, rem_byte(k)); - fligs++; - } - set_ligature_item(cligs[fligs], - (char) (op_byte(k) * 2 + 1), - next_char(k), rem_byte(k)); - fligs++; - } - } - if (skip_byte(k) == 0) { - k++; - } else { - if (skip_byte(k) >= stop_flag) - break; - k += skip_byte(k) + 1; - } - } - if (fkerns > 0 || fligs > 0) { - co = get_charinfo(f, i); - if (fkerns > 0) { - set_kern_item(ckerns[fkerns], end_kern, 0); - fkerns++; - set_charinfo_kerns(co, ckerns); - } - if (fligs > 0) { - set_ligature_item(cligs[fligs], 0, end_ligature, 0); - fligs++; - set_charinfo_ligatures(co, cligs); - } - set_charinfo_remainder(co, 0); - } - } - } - - - /* Make final adjustments and |goto done| */ - - /* Now to wrap it up, we have checked all the necessary things about the \.{TFM} - file, and all we need to do is put the finishing touches on the data for - the new font. - */ - - if (bchar != 65536) { - co = copy_charinfo(char_info(f, bchar)); - set_right_boundary(f, co); - } - - tfm_success; -} diff --git a/Build/source/texk/web2c/luatexdir/font/tounicode.w b/Build/source/texk/web2c/luatexdir/font/tounicode.c index 441a10dd5cf..f0449aff957 100644 --- a/Build/source/texk/web2c/luatexdir/font/tounicode.w +++ b/Build/source/texk/web2c/luatexdir/font/tounicode.c @@ -1,41 +1,46 @@ -% tounicode.w -% -% Copyright 2006 Han The Thanh, <thanh@@pdftex.org> -% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org> -% -% This file is part of LuaTeX. -% -% LuaTeX 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. -% -% LuaTeX 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 Lesser General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License along -% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +/* -@ @c +Copyright 2006 Han The Thanh, <thanh@pdftex.org> +Copyright 2006-2010 Taco Hoekwater <taco@luatex.org> +This file is part of LuaTeX. + +LuaTeX 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. + +LuaTeX 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU General Public License along +with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +*/ #include "ptexlib.h" -@ @c #define isXdigit(c) (isdigit(c) || ('A' <= (c) && (c) <= 'F')) -#define UNI_UNDEF -1 -#define UNI_STRING -2 /* string allocated by |def_tounicode()| */ -#define UNI_EXTRA_STRING -3 /* string allocated by |set_glyph_unicode()| */ + +/*tex + + |UNIC_STRING| is a string allocated by |def_tounicode| while + |UNI_EXTRA_STRING| is one allocated by |set_glyph_unicode|. + +*/ + +#define UNI_UNDEF -1 +#define UNI_STRING -2 +#define UNI_EXTRA_STRING -3 static struct avl_table *glyph_unicode_tree = NULL; static int comp_glyph_unicode_entry(const void *pa, const void *pb, void *p) { (void) p; - return strcmp(((const glyph_unicode_entry *) pa)->name, - ((const glyph_unicode_entry *) pb)->name); + return strcmp(((const glyph_unicode_entry *) pa)->name, ((const glyph_unicode_entry *) pb)->name); } static glyph_unicode_entry *new_glyph_unicode_entry(void) @@ -54,7 +59,6 @@ static void destroy_glyph_unicode_entry(void *pa, void *pb) (void) pb; xfree(e->name); if (e->code == UNI_STRING) { - assert(e->unicode_seq != NULL); xfree(e->unicode_seq); } } @@ -65,31 +69,34 @@ void glyph_unicode_free(void) avl_destroy(glyph_unicode_tree, destroy_glyph_unicode_entry); } -@ @c void def_tounicode(str_number glyph, str_number unistr) { char buf[SMALL_BUF_SIZE], *p, *ph; char buf2[SMALL_BUF_SIZE], *q; - int valid_unistr; /* 0: invalid; 1: unicode value; 2: string */ + /*tex |0| is invalid, |1| an \UNICODE\ value and |2| a string */ + int valid_unistr; int i, l; glyph_unicode_entry *gu, t; void **aa; - p = makecstring(glyph); assert(strlen(p) < SMALL_BUF_SIZE); strcpy(buf, p); free(p); p = makecstring(unistr); ph = p; + /*tex Ignore leading spaces. */ while (*p == ' ') - p++; /* ignore leading spaces */ + p++; l = (int) strlen(p); + /*tex Ignore traling spaces. */ while (l > 0 && p[l - 1] == ' ') - l--; /* ignore traling spaces */ - valid_unistr = 1; /* a unicode value is the most common case */ + l--; + /*tex A \UNICODE\ value is the most common case. */ + valid_unistr = 1; for (i = 0; i < l; i++) { + /*tex If a space occurs we treat this entry as a string. */ if (p[i] == ' ') - valid_unistr = 2; /* if a space occurs we treat this entry as a string */ + valid_unistr = 2; else if (!isXdigit((unsigned char)p[i])) { valid_unistr = 0; break; @@ -100,23 +107,21 @@ void def_tounicode(str_number glyph, str_number unistr) return; } if (glyph_unicode_tree == NULL) { - glyph_unicode_tree = - avl_create(comp_glyph_unicode_entry, NULL, &avl_xallocator); - assert(glyph_unicode_tree != NULL); + glyph_unicode_tree = avl_create(comp_glyph_unicode_entry, NULL, &avl_xallocator); } t.name = buf; - /* allow overriding existing entries */ + /*tex Allow overriding existing entries. */ if ((gu = (glyph_unicode_entry *) avl_find(glyph_unicode_tree, &t)) != NULL) { if (gu->code == UNI_STRING) { - assert(gu->unicode_seq != NULL); xfree(gu->unicode_seq); } - } else { /* make new entry */ + } else { + /*tex Make a new entry. */ gu = new_glyph_unicode_entry(); gu->name = xstrdup(buf); } - if (valid_unistr == 2) { /* a string with space(s) */ - /* copy p to buf2, ignoring spaces */ + if (valid_unistr == 2) { + /*tex A string can have space(s) that we ignore by copying |p| to |buf2|. */ for (q = buf2; *p != 0; p++) if (*p != ' ') *q++ = *p; @@ -125,28 +130,24 @@ void def_tounicode(str_number glyph, str_number unistr) gu->unicode_seq = xstrdup(buf2); } else { i = sscanf(p, "%lX", &(gu->code)); - assert(i == 1); } aa = avl_probe(glyph_unicode_tree, gu); assert(aa != NULL); free(ph); } - -@ @c static long check_unicode_value(char *s, boolean multiple_value) { int l = (int) strlen(s); int i; - long code = 0; /* anything that is not |UNI_UNDEF| will do */ - + /*tex Anything that is not |UNI_UNDEF| will do: */ + long code = 0; if (l == 0) return UNI_UNDEF; if (multiple_value && l % 4 != 0) return UNI_UNDEF; if (!multiple_value && !(4 <= l && l <= 6)) return UNI_UNDEF; - for (i = 0; i < l; i++) { if (!isXdigit((unsigned char)s[i])) return UNI_UNDEF; @@ -171,33 +172,33 @@ static long check_unicode_value(char *s, boolean multiple_value) return code; } -@ This function set proper values to |*gp| based on |s|; in case it returns - |gp->code == UNI_EXTRA_STRING| then the caller is responsible for freeing - |gp->unicode_seq| too. -@c +/* + + This function set proper values to |*gp| based on |s|; in case it returns + |gp->code == UNI_EXTRA_STRING| then the caller is responsible for freeing + |gp->unicode_seq| too. + +*/ + static void set_glyph_unicode(char *s, glyph_unicode_entry * gp) { char buf[SMALL_BUF_SIZE], buf2[SMALL_BUF_SIZE], *p; long code; boolean last_component; glyph_unicode_entry tmp, *ptmp; - - /* skip dummy entries */ + /*tex Skip dummy entries. */ if (s == NULL || s == notdef) return; - - /* strip everything after the first dot */ + /*tex Strip everything after the first dot. */ p = strchr(s, '.'); if (p != NULL) { *buf = 0; strncat(buf, s, (size_t) (p - s)); s = buf; } - if (strlen(s) == 0) return; - - /* check for case of multiple components separated by |'_'| */ + /*tex Check for case of multiple components separated by |_|. */ p = strchr(s, '_'); if (p != NULL) { assert(strlen(s) < sizeof(buf)); @@ -213,20 +214,26 @@ static void set_glyph_unicode(char *s, glyph_unicode_entry * gp) tmp.code = UNI_UNDEF; set_glyph_unicode(s, &tmp); switch (tmp.code) { - case UNI_UNDEF: /* not found, do nothing */ + case UNI_UNDEF: + /*tex Not found, do nothing. */ break; - case UNI_STRING: /* s matched an entry with string value in the database */ + case UNI_STRING: + /*tex |s| matched an entry with string value in the database. */ assert(tmp.unicode_seq != NULL); assert(strlen(buf2) + strlen(tmp.unicode_seq) < sizeof(buf2)); strcat(buf2, tmp.unicode_seq); break; - case UNI_EXTRA_STRING: /* s is a multiple value of form "uniXXXX" */ + case UNI_EXTRA_STRING: + /*tex |s| is a multiple value of form "uniXXXX" */ assert(strlen(buf2) + strlen(tmp.unicode_seq) < sizeof(buf2)); strcat(buf2, tmp.unicode_seq); xfree(tmp.unicode_seq); break; - default: /* s matched an entry with numeric value in the - database, or a value derived from "uXXXX" */ + default: + /*tex + |s| matched an entry with numeric value in the database, or a + value derived from |uXXXX|. + */ assert(tmp.code >= 0); strcat(buf2, utf16be_str(tmp.code)); } @@ -243,8 +250,7 @@ static void set_glyph_unicode(char *s, glyph_unicode_entry * gp) gp->unicode_seq = xstrdup(buf2); return; } - - /* lookup for glyph name in the database */ + /*tex Lookup glyph name in the database. */ tmp.name = s; tmp.code = UNI_UNDEF; ptmp = (glyph_unicode_entry *) avl_find(glyph_unicode_tree, &tmp); @@ -253,23 +259,24 @@ static void set_glyph_unicode(char *s, glyph_unicode_entry * gp) gp->unicode_seq = ptmp->unicode_seq; return; } - - /* check for case of "uniXXXX" (multiple 4-hex-digit values allowed) */ + /*tex Check for case of |uniXXXX|, multiple 4-hex-digit values allowed. */ if (str_prefix(s, "uni")) { p = s + strlen("uni"); code = check_unicode_value(p, true); if (code != UNI_UNDEF) { - if (strlen(p) == 4) /* single value */ + if (strlen(p) == 4) { + /*tex Single value: */ gp->code = code; - else { /* multiple value */ + } else { + /*tex Multiple value: */ gp->code = UNI_EXTRA_STRING; gp->unicode_seq = xstrdup(p); } } - return; /* since the last case cannot happen */ + /*tex Since the last case cannot happen: */ + return; } - - /* check for case of "uXXXX" (single value up to 6 hex digits) */ + /*tex Check for case of |uXXXX|, a single value up to 6 hex digits. */ if (str_prefix(s, "u")) { p = s + strlen("u"); code = check_unicode_value(p, false); @@ -280,9 +287,7 @@ static void set_glyph_unicode(char *s, glyph_unicode_entry * gp) } } -@ @c -static void set_cid_glyph_unicode(long index, glyph_unicode_entry * gp, - internal_font_number f) +static void set_cid_glyph_unicode(long index, glyph_unicode_entry * gp, internal_font_number f) { char *s; if (font_tounicode(f)) { @@ -290,15 +295,14 @@ static void set_cid_glyph_unicode(long index, glyph_unicode_entry * gp, gp->code = UNI_EXTRA_STRING; gp->unicode_seq = xstrdup(s); } else { - /* no fallback as we're providing them ourselves */ + /*tex No fall back as we're providing them ourselves. */ } } else { - /* fallback */ + /*tex Fall back. */ gp->code = index; } } -@ @c int write_tounicode(PDF pdf, char **glyph_names, char *name) { char buf[SMALL_BUF_SIZE], *p; @@ -314,64 +318,75 @@ int write_tounicode(PDF pdf, char **glyph_names, char *name) return 0; } strcpy(buf, name); - if ((p = strrchr(buf, '.')) != NULL && strcmp(p, ".enc") == 0) - *p = 0; /* strip ".enc" from encoding name */ - else - strcat(buf, builtin_suffix); /* ".enc" not present, this is a builtin - encoding so the name is eg "cmr10-builtin" */ + if ((p = strrchr(buf, '.')) != NULL && strcmp(p, ".enc") == 0) { + /*tex + Strip |.enc| from encoding name. + */ + *p = 0; + } else { + /* + The suffix |.enc| is not present so this is a builtin encoding so the + name becomes e.g. |cmr10-builtin|. + */ + strcat(buf, builtin_suffix); + } objnum = pdf_create_obj(pdf, obj_type_others, 0); pdf_begin_obj(pdf, objnum, OBJSTM_NEVER); pdf_begin_dict(pdf); pdf_dict_add_streaminfo(pdf); pdf_end_dict(pdf); pdf_begin_stream(pdf); - pdf_printf(pdf, "%%!PS-Adobe-3.0 Resource-CMap\n"@/ - "%%%%DocumentNeededResources: ProcSet (CIDInit)\n"@/ - "%%%%IncludeResource: ProcSet (CIDInit)\n"@/ - "%%%%BeginResource: CMap (TeX-%s-0)\n"@/ - "%%%%Title: (TeX-%s-0 TeX %s 0)\n"@/ - "%%%%Version: 1.000\n"@/ - "%%%%EndComments\n"@/ - "/CIDInit /ProcSet findresource begin\n"@/ - "12 dict begin\n"@/ - "begincmap\n"@/ - "/CIDSystemInfo\n"@/ - "<< /Registry (TeX)\n"@/ - "/Ordering (%s)\n"@/ - "/Supplement 0\n"@/ - ">> def\n"@/ - "/CMapName /TeX-%s-0 def\n"@/ - "/CMapType 2 def\n"@/ - "1 begincodespacerange\n"@/ - "<00> <FF>\n" "endcodespacerange\n", buf, buf, buf, buf, buf); - - /* set gtab */ + pdf_printf(pdf, + "%%!PS-Adobe-3.0 Resource-CMap\n" + "%%%%DocumentNeededResources: ProcSet (CIDInit)\n" + "%%%%IncludeResource: ProcSet (CIDInit)\n" + "%%%%BeginResource: CMap (TeX-%s-0)\n" + "%%%%Title: (TeX-%s-0 TeX %s 0)\n" + "%%%%Version: 1.000\n" + "%%%%EndComments\n" + "/CIDInit /ProcSet findresource begin\n" + "12 dict begin\n" + "begincmap\n" + "/CIDSystemInfo\n" + "<< /Registry (TeX)\n" + "/Ordering (%s)\n" + "/Supplement 0\n" + ">> def\n" + "/CMapName /TeX-%s-0 def\n" + "/CMapType 2 def\n" + "1 begincodespacerange\n" + "<00> <FF>\n" "endcodespacerange\n", + buf, buf, buf, buf, buf); + /*tex Set gtab: */ for (i = 0; i < 256; ++i) { gtab[i].code = UNI_UNDEF; set_glyph_unicode(glyph_names[i], >ab[i]); } gtab[256].code = UNI_UNDEF; - - /* set |range_size| */ + /*tex Set |range_size|: */ for (i = 0; i < 256;) { if (gtab[i].code == UNI_STRING || gtab[i].code == UNI_EXTRA_STRING) { - range_size[i] = 1; /* single entry */ + /*tex Single entry: */ + range_size[i] = 1; i++; } else if (gtab[i].code == UNI_UNDEF) { - range_size[i] = 0; /* no entry */ + /*tex No entry: */ + range_size[i] = 0; i++; - } else { /* gtab[i].code >= 0 */ + } else { + /*tex |gtab[i].code >= 0| */ j = i; - while (i < 256 && gtab[i + 1].code >= 0 && - gtab[i].code + 1 == gtab[i + 1].code) + while (i < 256 && gtab[i + 1].code >= 0 && gtab[i].code + 1 == gtab[i + 1].code) i++; - /* at this point i is the last entry of the subrange */ - i++; /* move i to the next entry */ + /*tex + At this point |i| is the last entry of the subrange so we move |i| to + the next entry. + */ + i++; range_size[j] = (short) (i - j); } } - - /* calculate |bfrange_count| and |bfchar_count| */ + /*tex Calculate |bfrange_count| and |bfchar_count|. */ bfrange_count = 0; bfchar_count = 0; for (i = 0; i < 256;) { @@ -384,8 +399,7 @@ int write_tounicode(PDF pdf, char **glyph_names, char *name) } else i++; } - - /* write out bfrange */ + /*tex Write out |bfrange|. */ i = 0; write_bfrange: if (bfrange_count > 100) @@ -405,8 +419,7 @@ int write_tounicode(PDF pdf, char **glyph_names, char *name) pdf_printf(pdf, "endbfrange\n"); if (bfrange_count > 0) goto write_bfrange; - - /* write out bfchar */ + /*tex Write out |bfchar|. */ i = 0; write_bfchar: if (bfchar_count > 100) @@ -421,7 +434,7 @@ int write_tounicode(PDF pdf, char **glyph_names, char *name) i += range_size[i]; else if (range_size[i] == 0) i++; - else /* |range_size[i] == 1| */ + else break; } assert(i < 256 && gtab[i].code != UNI_UNDEF); @@ -435,66 +448,63 @@ int write_tounicode(PDF pdf, char **glyph_names, char *name) pdf_printf(pdf, "endbfchar\n"); if (bfchar_count > 0) goto write_bfchar; - - /* free strings allocated by |set_glyph_unicode()| */ + /*tex Free strings allocated by |set_glyph_unicode|. */ for (i = 0; i < 256; ++i) { if (gtab[i].code == UNI_EXTRA_STRING) xfree(gtab[i].unicode_seq); } - - pdf_printf(pdf, "endcmap\n" - "CMapName currentdict /CMap defineresource pop\n" - "end\n" "end\n" "%%%%EndResource\n" "%%%%EOF\n"); + pdf_printf(pdf, + "endcmap\n" + "CMapName currentdict /CMap defineresource pop\n" + "end\n" + "end\n" + "%%%%EndResource\n" + "%%%%EOF\n"); pdf_end_stream(pdf); pdf_end_obj(pdf); return objnum; } -@ @c int write_cid_tounicode(PDF pdf, fo_entry * fo, internal_font_number f) { - static int range_size[65537]; static glyph_unicode_entry gtab[65537]; int objnum; int i, j, k; int bfchar_count, bfrange_count, subrange_count; char *buf; - - assert(fo->fd->fontname); buf = xmalloc((unsigned) (strlen(fo->fd->fontname) + 8)); - sprintf(buf, "%s-%s", - (fo->fd->subset_tag != NULL ? fo->fd->subset_tag : "UCS"), - fo->fd->fontname); - + sprintf(buf, "%s-%s", (fo->fd->subset_tag != NULL ? fo->fd->subset_tag : "UCS"), fo->fd->fontname); objnum = pdf_create_obj(pdf, obj_type_others, 0); pdf_begin_obj(pdf, objnum, OBJSTM_NEVER); pdf_begin_dict(pdf); pdf_dict_add_streaminfo(pdf); pdf_end_dict(pdf); pdf_begin_stream(pdf); - pdf_printf(pdf, "%%!PS-Adobe-3.0 Resource-CMap\n"@/ - "%%%%DocumentNeededResources: ProcSet (CIDInit)\n"@/ - "%%%%IncludeResource: ProcSet (CIDInit)\n"@/ - "%%%%BeginResource: CMap (TeX-%s-0)\n"@/ - "%%%%Title: (TeX-%s-0 TeX %s 0)\n"@/ - "%%%%Version: 1.000\n"@/ - "%%%%EndComments\n"@/ - "/CIDInit /ProcSet findresource begin\n"@/ - "12 dict begin\n"@/ - "begincmap\n"@/ - "/CIDSystemInfo\n"@/ - "<< /Registry (TeX)\n"@/ - "/Ordering (%s)\n"@/ - "/Supplement 0\n"@/ - ">> def\n"@/ - "/CMapName /TeX-Identity-%s def\n"@/ - "/CMapType 2 def\n"@/ - "1 begincodespacerange\n"@/ - "<0000> <FFFF>\n"@/ - "endcodespacerange\n", buf, buf, buf, buf, buf); + pdf_printf(pdf, + "%%!PS-Adobe-3.0 Resource-CMap\n" + "%%%%DocumentNeededResources: ProcSet (CIDInit)\n" + "%%%%IncludeResource: ProcSet (CIDInit)\n" + "%%%%BeginResource: CMap (TeX-%s-0)\n" + "%%%%Title: (TeX-%s-0 TeX %s 0)\n" + "%%%%Version: 1.000\n" + "%%%%EndComments\n" + "/CIDInit /ProcSet findresource begin\n" + "12 dict begin\n" + "begincmap\n" + "/CIDSystemInfo\n" + "<< /Registry (TeX)\n" + "/Ordering (%s)\n" + "/Supplement 0\n" + ">> def\n" + "/CMapName /TeX-Identity-%s def\n" + "/CMapType 2 def\n" + "1 begincodespacerange\n" + "<0000> <FFFF>\n" + "endcodespacerange\n", + buf, buf, buf, buf, buf); xfree(buf); - /* set up gtab */ + /*tex Set up |gtab|: */ for (i = 0; i < 65537; ++i) { gtab[i].code = UNI_UNDEF; } @@ -510,29 +520,33 @@ int write_cid_tounicode(PDF pdf, fo_entry * fo, internal_font_number f) } } } - - /* set |range_size| */ + /*tex Set |range_size|: */ for (i = 0; i < 65536;) { if (gtab[i].code == UNI_STRING || gtab[i].code == UNI_EXTRA_STRING) { - range_size[i] = 1; /* single entry */ + /*tex Single entry. */ + range_size[i] = 1; i++; } else if (gtab[i].code == UNI_UNDEF) { - range_size[i] = 0; /* no entry */ + /*tex No entry. */ + range_size[i] = 0; i++; - } else { /* |gtab[i].code >= 0| */ + } else { + /*tex |gtab[i].code >= 0| */ j = i; k = i % 256; while (i < 65536 && k<255 && gtab[i + 1].code >= 0 && gtab[i].code + 1 == gtab[i + 1].code) { i++; k++; } - /* at this point i is the last entry of the subrange */ - i++; /* move i to the next entry */ + /* tex + At this point |i| is the last entry of the subrange so we move + |i| to the next entry + */ + i++; range_size[j] = i - j; } } - - /* calculate |bfrange_count| and |bfchar_count| */ + /*tex Calculate |bfrange_count| and |bfchar_count|. */ bfrange_count = 0; bfchar_count = 0; for (i = 0; i < 65536;) { @@ -545,8 +559,7 @@ int write_cid_tounicode(PDF pdf, fo_entry * fo, internal_font_number f) } else i++; } - - /* write out bfrange */ + /*tex Write out |bfrange|. */ i = 0; write_bfrange: if (bfrange_count > 100) @@ -558,16 +571,13 @@ int write_cid_tounicode(PDF pdf, fo_entry * fo, internal_font_number f) for (j = 0; j < subrange_count; j++) { while (range_size[i] <= 1 && i < 65536) i++; - assert(i < 65536); - pdf_printf(pdf, "<%04X> <%04X> <%s>\n", i, i + range_size[i] - 1, - utf16be_str(gtab[i].code)); + pdf_printf(pdf, "<%04X> <%04X> <%s>\n", i, i + range_size[i] - 1, utf16be_str(gtab[i].code)); i += range_size[i]; } pdf_printf(pdf, "endbfrange\n"); if (bfrange_count > 0) goto write_bfrange; - - /* write out bfchar */ + /*tex Write out |bfchar| */ i = 0; write_bfchar: if (bfchar_count > 100) @@ -582,12 +592,12 @@ int write_cid_tounicode(PDF pdf, fo_entry * fo, internal_font_number f) i += range_size[i]; else if (range_size[i] == 0) i++; - else /* |range_size[i] == 1| */ + else + /* |range_size[i] == 1| */ break; } assert(i < 65536 && gtab[i].code != UNI_UNDEF); if (gtab[i].code == UNI_STRING || gtab[i].code == UNI_EXTRA_STRING) { - assert(gtab[i].unicode_seq != NULL); pdf_printf(pdf, "<%04X> <%s>\n", i, gtab[i].unicode_seq); } else pdf_printf(pdf, "<%04X> <%s>\n", i, utf16be_str(gtab[i].code)); @@ -596,16 +606,18 @@ int write_cid_tounicode(PDF pdf, fo_entry * fo, internal_font_number f) pdf_printf(pdf, "endbfchar\n"); if (bfchar_count > 0) goto write_bfchar; - - /* free strings allocated by |set_glyph_unicode()| */ + /*tex Free strings allocated by |set_glyph_unicode|: */ for (i = 0; i < 65536; ++i) { if (gtab[i].code == UNI_EXTRA_STRING) xfree(gtab[i].unicode_seq); } - - pdf_printf(pdf, "endcmap\n" - "CMapName currentdict /CMap defineresource pop\n" - "end\n" "end\n" "%%%%EndResource\n" "%%%%EOF\n"); + pdf_printf(pdf, + "endcmap\n" + "CMapName currentdict /CMap defineresource pop\n" + "end\n" + "end\n" + "%%%%EndResource\n" + "%%%%EOF\n"); pdf_end_stream(pdf); pdf_end_obj(pdf); return objnum; diff --git a/Build/source/texk/web2c/luatexdir/font/tt_glyf.w b/Build/source/texk/web2c/luatexdir/font/tt_glyf.c index c0f17e5ab59..750e126aa6a 100644 --- a/Build/source/texk/web2c/luatexdir/font/tt_glyf.w +++ b/Build/source/texk/web2c/luatexdir/font/tt_glyf.c @@ -1,28 +1,25 @@ -% tt_glyf.w -% -% Copyright 2002 by Jin-Hwan Cho and Shunsaku Hirata, -% the dvipdfmx project team <dvipdfmx@@project.ktug.or.kr> -% Copyright 2006-2012 Taco Hoekwater <taco@@luatex.org> -% -% This file is part of LuaTeX. -% -% LuaTeX 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. -% -% LuaTeX 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 Lesser General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License along -% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +/* -@* Subsetting glyf, updating loca, hmtx, etc. +Copyright 2002 by Jin-Hwan Cho and Shunsaku Hirata, +the dvipdfmx project team <dvipdfmx@project.ktug.or.kr> +Copyright 2006-2012 Taco Hoekwater <taco@luatex.org> -@ @c +This file is part of LuaTeX. +LuaTeX 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. + +LuaTeX 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU General Public License along +with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +*/ #include "ptexlib.h" @@ -31,7 +28,6 @@ #include "font/tt_glyf.h" #include "font/writettf.h" -@ @c #define NUM_GLYPH_LIMIT 65534 #define TABLE_DATA_ALLOC_SIZE 40960 #define GLYPH_ARRAY_ALLOC_SIZE 256 @@ -39,55 +35,41 @@ static USHORT find_empty_slot(struct tt_glyphs *g) { USHORT gid; - - ASSERT(g); - for (gid = 0; gid < NUM_GLYPH_LIMIT; gid++) { if (!(g->used_slot[gid / 8] & (1 << (7 - (gid % 8))))) break; } if (gid == NUM_GLYPH_LIMIT) normal_error("ttf","no empty glyph slot available."); - return gid; } USHORT tt_find_glyph(struct tt_glyphs * g, USHORT gid) { USHORT idx, new_gid = 0; - - ASSERT(g); - for (idx = 0; idx < g->num_glyphs; idx++) { if (gid == g->gd[idx].ogid) { new_gid = g->gd[idx].gid; break; } } - return new_gid; } USHORT tt_get_index(struct tt_glyphs * g, USHORT gid) { USHORT idx; - - ASSERT(g); - for (idx = 0; idx < g->num_glyphs; idx++) { if (gid == g->gd[idx].gid) break; } if (idx == g->num_glyphs) idx = 0; - return idx; } USHORT tt_add_glyph(struct tt_glyphs * g, USHORT gid, USHORT new_gid) { - ASSERT(g); - if (g->used_slot[new_gid / 8] & (1 << (7 - (new_gid % 8)))) { formatted_warning("ttf","slot %u already used", new_gid); } else { @@ -102,28 +84,21 @@ USHORT tt_add_glyph(struct tt_glyphs * g, USHORT gid, USHORT new_gid) g->gd[g->num_glyphs].ogid = gid; g->gd[g->num_glyphs].length = 0; g->gd[g->num_glyphs].data = NULL; - g->used_slot[new_gid / 8] = - (unsigned char) (g->used_slot[new_gid / - 8] | (1 << (7 - (new_gid % 8)))); + g->used_slot[new_gid / 8] = (unsigned char) (g->used_slot[new_gid / 8] | (1 << (7 - (new_gid % 8)))); g->num_glyphs++; } - if (new_gid > g->last_gid) { g->last_gid = new_gid; } - return new_gid; } +/*tex Initialization */ -@ Initialization -@c struct tt_glyphs *tt_build_init(void) { struct tt_glyphs *g; - g = NEW(1, struct tt_glyphs); - g->num_glyphs = 0; g->max_glyphs = 0; g->last_gid = 0; @@ -134,7 +109,6 @@ struct tt_glyphs *tt_build_init(void) g->used_slot = NEW(8192, unsigned char); memset(g->used_slot, 0, 8192); tt_add_glyph(g, 0, 0); - return g; } @@ -159,37 +133,33 @@ static int glyf_cmp(const void *v1, const void *v2) { int cmp = 0; const struct tt_glyph_desc *sv1, *sv2; - sv1 = (const struct tt_glyph_desc *) v1; sv2 = (const struct tt_glyph_desc *) v2; - if (sv1->gid == sv2->gid) cmp = 0; else if (sv1->gid < sv2->gid) cmp = -1; else cmp = 1; - return cmp; } -@ @c int tt_build_tables(sfnt * sfont, struct tt_glyphs *g, fd_entry * fd) { char *hmtx_table_data = NULL, *loca_table_data = NULL; char *glyf_table_data = NULL; ULONG hmtx_table_size, loca_table_size, glyf_table_size, glyf_table_used; - /* some information available from other TrueType table */ + /*tex Some information available from other \TRUETYPE\ table. */ struct tt_head_table *head = NULL; struct tt_hhea_table *hhea = NULL; struct tt_maxp_table *maxp = NULL; struct tt_longMetrics *hmtx, *vmtx = NULL; struct tt_os2__table *os2; - /* temp */ + /*tex Something temporary: */ ULONG *location, offset; long i; - USHORT *w_stat; /* Estimate most frequently appeared width */ - + /*tex Estimate the most frequently appeared width. */ + USHORT *w_stat; int tex_font = fd->tex_font; int streamprovider = 0; int callback_id = 0 ; @@ -197,60 +167,35 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g, fd_entry * fd) streamprovider = font_streamprovider(tex_font); callback_id = callback_defined(glyph_stream_provider_callback); } - - ASSERT(g); - if (sfont->type != SFNT_TYPE_TRUETYPE && sfont->type != SFNT_TYPE_TTC) normal_error("ttf","invalid font type"); - if (g->num_glyphs > NUM_GLYPH_LIMIT) normal_error("ttf","too many glyphs"); - - /* - Read head, hhea, maxp, loca: - - unitsPerEm --> head - - numHMetrics --> hhea - - indexToLocFormat --> head - - numGlyphs --> maxp - */ head = tt_read_head_table(sfont); hhea = tt_read_hhea_table(sfont); maxp = tt_read_maxp_table(sfont); - if (hhea->metricDataFormat != 0) normal_error("ttf","unknown metricDataFormat"); - g->emsize = head->unitsPerEm; - sfnt_locate_table(sfont, "hmtx"); hmtx = tt_read_longMetrics(sfont, maxp->numGlyphs, hhea->numberOfHMetrics); - os2 = tt_read_os2__table(sfont); if (os2) { g->default_advh = (USHORT) (os2->sTypoAscender - os2->sTypoDescender); g->default_tsb = (SHORT) (g->default_advh - os2->sTypoAscender); - - /* dvipdfmx does this elsewhere! */ + /*tex |dvipdfmx| does this elsewhere! */ fd_cur->font_dim[STEMV_CODE].val = (os2->usWeightClass / 65) * (os2->usWeightClass / 65) + 50; } - if (sfnt_find_table_pos(sfont, "vmtx") > 0) { struct tt_vhea_table *vhea; vhea = tt_read_vhea_table(sfont); sfnt_locate_table(sfont, "vmtx"); - vmtx = - tt_read_longMetrics(sfont, maxp->numGlyphs, - vhea->numOfLongVerMetrics); + vmtx = tt_read_longMetrics(sfont, maxp->numGlyphs, vhea->numOfLongVerMetrics); RELEASE(vhea); } else { vmtx = NULL; } - sfnt_locate_table(sfont, "loca"); location = NEW(maxp->numGlyphs + 1, ULONG); if (head->indexToLocFormat == 0) { @@ -262,34 +207,27 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g, fd_entry * fd) } else { normal_error("ttf","unknown IndexToLocFormat"); } - w_stat = NEW(g->emsize + 2, USHORT); - memset(w_stat, 0, - (size_t) (sizeof(USHORT) * ((long unsigned) g->emsize + 2))); - /* - * Read glyf table. - */ + memset(w_stat, 0, (size_t) (sizeof(USHORT) * ((long unsigned) g->emsize + 2))); offset = sfnt_locate_table(sfont, "glyf"); - /* - The |num_glyphs| may grow when composite glyph is found. - A component of glyph refered by a composite glyph is appended - to |used_glyphs| if it is not already registered in |used_glyphs|. - Glyph programs of composite glyphs are modified so that it - correctly refer to new gid of their components. - */ + /*tex + + The |num_glyphs| may grow when composite glyph is found. A component of + glyph refered by a composite glyph is appended to |used_glyphs| if it is + not already registered in |used_glyphs|. Glyph programs of composite + glyphs are modified so that it correctly refer to new gid of their + components. + */ for (i = 0; i < NUM_GLYPH_LIMIT; i++) { - USHORT gid; /* old gid */ + USHORT gid; ULONG loc, len; BYTE *p, *endptr; SHORT number_of_contours; - - if (i >= g->num_glyphs) /* finished */ + if (i >= g->num_glyphs) break; - gid = g->gd[i].ogid; if (gid >= maxp->numGlyphs) formatted_error("ttf","invalid glyph index (gid %u)", gid); - loc = location[gid]; len = location[gid + 1] - loc; g->gd[i].advw = hmtx[gid].advance; @@ -306,52 +244,43 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g, fd_entry * fd) if (g->gd[i].advw <= g->emsize) { w_stat[g->gd[i].advw]++; } else { - w_stat[g->emsize + 1]++; /* larger than em */ + /*tex It's larger than em. */ + w_stat[g->emsize + 1]++; } - if (len == 0) { /* Does not contains any data. */ + if (len == 0) { + /*tex Does not contain any data. */ continue; } else if (len < 10) { formatted_error("ttf","invalid glyph data (gid %u)", gid); } - -/* todo: no need for this */ + /*tex There is no real need for this. */ g->gd[i].data = p = NEW(len, BYTE); endptr = p + len; - sfnt_seek_set(sfont, (long) (offset + loc)); number_of_contours = sfnt_get_short(sfont); p += sfnt_put_short(p, number_of_contours); - /* BoundingBox: FWord x 4 */ g->gd[i].llx = sfnt_get_short(sfont); g->gd[i].lly = sfnt_get_short(sfont); g->gd[i].urx = sfnt_get_short(sfont); g->gd[i].ury = sfnt_get_short(sfont); - /* |_FIXME_| */ -#if 1 - if (!vmtx) /* |vertOriginY == sTypeAscender| */ - g->gd[i].tsb = - (SHORT) (g->default_advh - g->default_tsb - g->gd[i].ury); -#endif + if (!vmtx) { + /*tex A fix: |vertOriginY == sTypeAscender| */ + g->gd[i].tsb = (SHORT) (g->default_advh - g->default_tsb - g->gd[i].ury); + } p += sfnt_put_short(p, g->gd[i].llx); p += sfnt_put_short(p, g->gd[i].lly); p += sfnt_put_short(p, g->gd[i].urx); p += sfnt_put_short(p, g->gd[i].ury); - - /* Read evrything else. */ + /*tex Read evrything else. */ sfnt_read(p, (int) len - 10, sfont); - /* - Fix GIDs of composite glyphs. - */ + /*tex Fix GIDs of composite glyphs. */ if (number_of_contours < 0) { - USHORT flags, cgid, new_gid; /* flag, gid of a component */ + USHORT flags, cgid, new_gid; do { if (p >= endptr) formatted_error("ttf","invalid glyph data (gid %u): %u bytes", gid, (unsigned int) len); - /* - * Flags and gid of component glyph are both USHORT. - */ flags = (USHORT) (((*p) << 8) | *(p + 1)); p += 2; cgid = (USHORT) (((*p) << 8) | *(p + 1)); @@ -363,34 +292,38 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g, fd_entry * fd) new_gid = tt_add_glyph(g, cgid, find_empty_slot(g)); } p += sfnt_put_ushort(p, new_gid); - /* - * Just skip remaining part. - */ + /*tex Just skip remaining part. */ p += (flags & ARG_1_AND_2_ARE_WORDS) ? 4 : 2; - if (flags & WE_HAVE_A_SCALE) /* F2Dot14 */ + if (flags & WE_HAVE_A_SCALE) { + /*tex |F2Dot14| */ p += 2; - else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) /* F2Dot14 x 2 */ + } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) { + /*tex two times |F2Dot14| */ p += 4; - else if (flags & WE_HAVE_A_TWO_BY_TWO) /* F2Dot14 x 4 */ + } else if (flags & WE_HAVE_A_TWO_BY_TWO) { + /*tex four times |F2Dot14| */ p += 8; + } } while (flags & MORE_COMPONENTS); - /* - TrueType instructions comes here: + /*tex + + TrueType instructions comes here. The call pattern is: - |length_of_instruction| (|ushort|) + \starttyping + |length_of_instruction| (|ushort|) + instruction (|byte * length_of_instruction|) + \stoptyping - instruction (|byte * length_of_instruction|) */ } } RELEASE(location); RELEASE(hmtx); - if (vmtx) + if (vmtx) { RELEASE(vmtx); - + } { int max_count = -1; - g->dw = g->gd[0].advw; for (i = 0; i < g->emsize + 1; i++) { if (w_stat[i] > max_count) { @@ -400,13 +333,11 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g, fd_entry * fd) } } RELEASE(w_stat); - qsort(g->gd, g->num_glyphs, sizeof(struct tt_glyph_desc), glyf_cmp); { USHORT prev, last_advw; char *p, *q; int padlen, num_hm_known; - glyf_table_size = 0UL; num_hm_known = 0; last_advw = g->gd[g->num_glyphs - 1].advw; @@ -419,17 +350,17 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g, fd_entry * fd) num_hm_known = 1; } } - /* All advance widths are same. */ + /*tex All advance widths are the same. */ if (!num_hm_known) { hhea->numberOfHMetrics = 1; } - hmtx_table_size = - (ULONG) (hhea->numberOfHMetrics * 2 + (g->last_gid + 1) * 2); + hmtx_table_size = (ULONG) (hhea->numberOfHMetrics * 2 + (g->last_gid + 1) * 2); + /*tex + + Choosing short format does not always give good result when + compressed. Sometimes increases size. - /* - Choosing short format does not always give good result - when compressed. Sometimes increases size. - */ + */ if (glyf_table_size < 0x20000UL) { head->indexToLocFormat = 0; loca_table_size = (ULONG) ((g->last_gid + 2) * 2); @@ -437,12 +368,10 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g, fd_entry * fd) head->indexToLocFormat = 1; loca_table_size = (ULONG) ((g->last_gid + 2) * 4); } - hmtx_table_data = p = NEW(hmtx_table_size, char); loca_table_data = q = NEW(loca_table_size, char); glyf_table_data = NEW(glyf_table_size, char); glyf_table_used = 0; - offset = 0UL; prev = 0; for (i = 0; i < g->num_glyphs; i++) { @@ -470,12 +399,10 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g, fd_entry * fd) } else { q += sfnt_put_ulong(q, (LONG) offset); } - if (callback_id > 0) { - lstring * result; long size = 0; - run_callback(callback_id, "ddd->L", tex_font, g->gd[i].gid, streamprovider, &result); /* this call can be sped up */ + run_callback(callback_id, "ddd->L", tex_font, g->gd[i].gid, streamprovider, &result); padlen = (int) ((result->l % 4) ? (4 - (result->l % 4)) : 0); size = (size_t) result->l + (ULONG) padlen; if (glyf_table_used + size >= glyf_table_size) { @@ -487,18 +414,15 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g, fd_entry * fd) memcpy(glyf_table_data + offset, (const char *) result->s, (size_t) result->l); offset += size; xfree(result); - } else { - padlen = (int) ((g->gd[i].length % 4) ? (4 - (g->gd[i].length % 4)) : 0); memset(glyf_table_data + offset, 0, (size_t) (g->gd[i].length + (ULONG) padlen)); memcpy(glyf_table_data + offset, g->gd[i].data, g->gd[i].length); offset += (g->gd[i].length + (ULONG) padlen); - } prev = g->gd[i].gid; RELEASE(g->gd[i].data); - /* free data here since it consume much memory */ + /*tex We free data here since it consume much memory. */ g->gd[i].length = 0; g->gd[i].data = NULL; } @@ -507,7 +431,6 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g, fd_entry * fd) } else { q += sfnt_put_ulong(q, (LONG) offset); } - sfnt_set_table(sfont, "hmtx", (char *) hmtx_table_data, hmtx_table_size); sfnt_set_table(sfont, "loca", (char *) loca_table_data, loca_table_size); if (callback_id > 0) { @@ -515,20 +438,17 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g, fd_entry * fd) } sfnt_set_table(sfont, "glyf", (char *) glyf_table_data, glyf_table_size); } - head->checkSumAdjustment = 0; maxp->numGlyphs = (USHORT) (g->last_gid + 1); - - /* TODO */ sfnt_set_table(sfont, "maxp", tt_pack_maxp_table(maxp), TT_MAXP_TABLE_SIZE); sfnt_set_table(sfont, "hhea", tt_pack_hhea_table(hhea), TT_HHEA_TABLE_SIZE); sfnt_set_table(sfont, "head", tt_pack_head_table(head), TT_HEAD_TABLE_SIZE); RELEASE(maxp); RELEASE(hhea); RELEASE(head); - if (os2) + if (os2) { RELEASE(os2); - + } return 0; } @@ -539,66 +459,33 @@ int tt_get_metrics(sfnt * sfont, struct tt_glyphs *g) struct tt_maxp_table *maxp = NULL; struct tt_longMetrics *hmtx, *vmtx = NULL; struct tt_os2__table *os2; - /* temp */ ULONG *location, offset; long i; USHORT *w_stat; - - ASSERT(g); - - if (sfont == NULL || -#ifdef XETEX - sfont->ft_face == NULL -#elif defined(pdfTeX) - sfont->buffer == NULL -#else - sfont->stream == NULL -#endif - ) + if (sfont == NULL || sfont->buffer == NULL) normal_error("ttf","file not opened"); - if (sfont->type != SFNT_TYPE_TRUETYPE && sfont->type != SFNT_TYPE_TTC) normal_error("ttf","invalid font type"); - - /* - Read head, hhea, maxp, loca: - - unitsPerEm --> head - - numHMetrics --> hhea - - indexToLocFormat --> head - - numGlyphs --> maxp - */ head = tt_read_head_table(sfont); hhea = tt_read_hhea_table(sfont); maxp = tt_read_maxp_table(sfont); - if (hhea->metricDataFormat != 0) normal_error("ttf","unknown metricDataFormat"); - g->emsize = head->unitsPerEm; - sfnt_locate_table(sfont, "hmtx"); hmtx = tt_read_longMetrics(sfont, maxp->numGlyphs, hhea->numberOfHMetrics); - os2 = tt_read_os2__table(sfont); g->default_advh = (USHORT) (os2->sTypoAscender - os2->sTypoDescender); g->default_tsb = (SHORT) (g->default_advh - os2->sTypoAscender); - if (sfnt_find_table_pos(sfont, "vmtx") > 0) { struct tt_vhea_table *vhea; vhea = tt_read_vhea_table(sfont); sfnt_locate_table(sfont, "vmtx"); - vmtx = - tt_read_longMetrics(sfont, maxp->numGlyphs, - vhea->numOfLongVerMetrics); + vmtx = tt_read_longMetrics(sfont, maxp->numGlyphs, vhea->numOfLongVerMetrics); RELEASE(vhea); } else { vmtx = NULL; } - sfnt_locate_table(sfont, "loca"); location = NEW(maxp->numGlyphs + 1, ULONG); if (head->indexToLocFormat == 0) { @@ -610,22 +497,16 @@ int tt_get_metrics(sfnt * sfont, struct tt_glyphs *g) } else { normal_error("ttf","inknown IndexToLocFormat"); } - w_stat = NEW(g->emsize + 2, USHORT); memset(w_stat, 0, (size_t) ((int) sizeof(USHORT) * (g->emsize + 2))); - /* - Read glyf table. - */ + /*tex Read glyf table. */ offset = sfnt_locate_table(sfont, "glyf"); for (i = 0; i < g->num_glyphs; i++) { - USHORT gid; /* old gid */ + USHORT gid; ULONG loc, len; - /*SHORT number_of_contours;*/ - gid = g->gd[i].ogid; if (gid >= maxp->numGlyphs) formatted_error("ttf","invalid glyph index (gid %u)", gid); - loc = location[gid]; len = location[gid + 1] - loc; g->gd[i].advw = hmtx[gid].advance; @@ -639,33 +520,30 @@ int tt_get_metrics(sfnt * sfont, struct tt_glyphs *g) } g->gd[i].length = len; g->gd[i].data = NULL; - if (g->gd[i].advw <= g->emsize) { w_stat[g->gd[i].advw]++; } else { - w_stat[g->emsize + 1]++; /* larger than em */ + /*tex It's larger than em: */ + w_stat[g->emsize + 1]++; } - - if (len == 0) { /* Does not contains any data. */ + if (len == 0) { + /*tex No data. */ continue; } else if (len < 10) { formatted_error("ttf","invalid glyph data (gid %u)", gid); } - sfnt_seek_set(sfont, (long) (offset + loc)); - /*number_of_contours = */(void)sfnt_get_short(sfont); - - /* BoundingBox: FWord x 4 */ + /*tex Skip the number of contours */ + (void)sfnt_get_short(sfont); + /*tex Fetch the BoundingBox. */ g->gd[i].llx = sfnt_get_short(sfont); g->gd[i].lly = sfnt_get_short(sfont); g->gd[i].urx = sfnt_get_short(sfont); g->gd[i].ury = sfnt_get_short(sfont); - /* |_FIXME_| */ -#if 1 - if (!vmtx) /* |vertOriginY == sTypeAscender| */ - g->gd[i].tsb = - (SHORT) (g->default_advh - g->default_tsb - g->gd[i].ury); -#endif + if (!vmtx) { + /*tex We fix |vertOriginY == sTypeAscender|. */ + g->gd[i].tsb = (SHORT) (g->default_advh - g->default_tsb - g->gd[i].ury); + } } RELEASE(location); RELEASE(hmtx); @@ -673,13 +551,11 @@ int tt_get_metrics(sfnt * sfont, struct tt_glyphs *g) RELEASE(hhea); RELEASE(head); RELEASE(os2); - - if (vmtx) + if (vmtx) { RELEASE(vmtx); - + } { int max_count = -1; - g->dw = g->gd[0].advw; for (i = 0; i < g->emsize + 1; i++) { if (w_stat[i] > max_count) { @@ -689,7 +565,5 @@ int tt_get_metrics(sfnt * sfont, struct tt_glyphs *g) } } RELEASE(w_stat); - - return 0; } diff --git a/Build/source/texk/web2c/luatexdir/font/tt_table.w b/Build/source/texk/web2c/luatexdir/font/tt_table.c index a4164f39d48..dfcd4d650cd 100644 --- a/Build/source/texk/web2c/luatexdir/font/tt_table.w +++ b/Build/source/texk/web2c/luatexdir/font/tt_table.c @@ -1,52 +1,41 @@ -% tt_table.w -% -% Copyright 2002 by Jin-Hwan Cho and Shunsaku Hirata, -% the dvipdfmx project team <dvipdfmx@@project.ktug.or.kr> -% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org> -% -% This file is part of LuaTeX. -% -% LuaTeX 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. -% -% LuaTeX 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 Lesser General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License along -% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +/* -@ @c +Copyright 2002 by Jin-Hwan Cho and Shunsaku Hirata, the dvipdfmx project + team <dvipdfmx@project.ktug.or.kr> +Copyright 2006-2010 Taco Hoekwater <taco@luatex.org> +This file is part of LuaTeX. -#include "ptexlib.h" +LuaTeX 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. + +LuaTeX 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 Lesser General Public License for more details. + +You should have received a copy of the GNU General Public License along with +LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +*/ +#include "ptexlib.h" #include <stdio.h> #include "font/sfnt.h" #include "font/tt_table.h" -@ tables contains information refered by other tables - - |maxp->numGlyphs, etc --> loca, etc| - - |hhea->numberOfHMetrics --> hmtx| +/*tex - |head->indexToLocFormat --> loca| + Tables contain information referred by other tables. - |head->glyphDataFormat --> glyf| +*/ -@c char *tt_pack_head_table(struct tt_head_table *table) { int i; char *p, *data; - if (table == NULL) normal_error("ttf","passed NULL pointer"); - p = data = NEW(TT_HEAD_TABLE_SIZE, char); p += sfnt_put_ulong(p, (LONG) table->version); p += sfnt_put_ulong(p, (LONG) table->fontRevision); @@ -69,7 +58,6 @@ char *tt_pack_head_table(struct tt_head_table *table) p += sfnt_put_short(p, table->fontDirectionHint); p += sfnt_put_short(p, table->indexToLocFormat); p += sfnt_put_short(p, table->glyphDataFormat); - return data; } @@ -77,11 +65,8 @@ struct tt_head_table *tt_read_head_table(sfnt * sfont) { int i; struct tt_head_table *table = NULL; - table = NEW(1, struct tt_head_table); - sfnt_locate_table(sfont, "head"); - table->version = sfnt_get_ulong(sfont); table->fontRevision = sfnt_get_ulong(sfont); table->checkSumAdjustment = sfnt_get_ulong(sfont); @@ -103,14 +88,12 @@ struct tt_head_table *tt_read_head_table(sfnt * sfont) table->fontDirectionHint = sfnt_get_short(sfont); table->indexToLocFormat = sfnt_get_short(sfont); table->glyphDataFormat = sfnt_get_short(sfont); - return table; } char *tt_pack_maxp_table(struct tt_maxp_table *table) { char *p, *data; - p = data = NEW(TT_MAXP_TABLE_SIZE, char); p += sfnt_put_ulong(p, (LONG) table->version); p += sfnt_put_ushort(p, table->numGlyphs); @@ -127,16 +110,13 @@ char *tt_pack_maxp_table(struct tt_maxp_table *table) p += sfnt_put_ushort(p, table->maxSizeOfInstructions); p += sfnt_put_ushort(p, table->maxComponentElements); p += sfnt_put_ushort(p, table->maxComponentDepth); - return data; } struct tt_maxp_table *tt_read_maxp_table(sfnt * sfont) { struct tt_maxp_table *table = NULL; - table = NEW(1, struct tt_maxp_table); - sfnt_locate_table(sfont, "maxp"); table->version = sfnt_get_ulong(sfont); table->numGlyphs = sfnt_get_ushort(sfont); @@ -153,7 +133,6 @@ struct tt_maxp_table *tt_read_maxp_table(sfnt * sfont) table->maxSizeOfInstructions = sfnt_get_ushort(sfont); table->maxComponentElements = sfnt_get_ushort(sfont); table->maxComponentDepth = sfnt_get_ushort(sfont); - return table; } @@ -161,7 +140,6 @@ char *tt_pack_hhea_table(struct tt_hhea_table *table) { int i; char *p, *data; - p = data = NEW(TT_HHEA_TABLE_SIZE, char); p += sfnt_put_ulong(p, (LONG) table->version); p += sfnt_put_short(p, table->Ascender); @@ -178,7 +156,6 @@ char *tt_pack_hhea_table(struct tt_hhea_table *table) } p += sfnt_put_short(p, table->metricDataFormat); p += sfnt_put_ushort(p, table->numberOfHMetrics); - return data; } @@ -186,9 +163,7 @@ struct tt_hhea_table *tt_read_hhea_table(sfnt * sfont) { int i; struct tt_hhea_table *table = NULL; - table = NEW(1, struct tt_hhea_table); - sfnt_locate_table(sfont, "hhea"); table->version = sfnt_get_ulong(sfont); table->Ascender = sfnt_get_short(sfont); @@ -207,23 +182,19 @@ struct tt_hhea_table *tt_read_hhea_table(sfnt * sfont) if (table->metricDataFormat != 0) normal_error("ttf","unknown metricDaraFormat"); table->numberOfHMetrics = sfnt_get_ushort(sfont); - return table; } -@ vhea -@c char *tt_pack_vhea_table(struct tt_vhea_table *table) { int i; char *p, *data; - p = data = NEW(TT_VHEA_TABLE_SIZE, char); p += sfnt_put_ulong(p, (LONG) table->version); p += sfnt_put_short(p, table->vertTypoAscender); p += sfnt_put_short(p, table->vertTypoDescender); p += sfnt_put_short(p, table->vertTypoLineGap); - p += sfnt_put_short(p, table->advanceHeightMax); /* ushort ? */ + p += sfnt_put_short(p, table->advanceHeightMax); p += sfnt_put_short(p, table->minTopSideBearing); p += sfnt_put_short(p, table->minBottomSideBearing); p += sfnt_put_short(p, table->yMaxExtent); @@ -234,7 +205,6 @@ char *tt_pack_vhea_table(struct tt_vhea_table *table) p += sfnt_put_short(p, table->reserved[i]); } p += sfnt_put_ushort(p, table->numOfLongVerMetrics); - return data; } @@ -242,15 +212,13 @@ struct tt_vhea_table *tt_read_vhea_table(sfnt * sfont) { int i; struct tt_vhea_table *table = NULL; - table = NEW(1, struct tt_vhea_table); - sfnt_locate_table(sfont, "vhea"); table->version = sfnt_get_ulong(sfont); table->vertTypoAscender = sfnt_get_short(sfont); table->vertTypoDescender = sfnt_get_short(sfont); table->vertTypoLineGap = sfnt_get_short(sfont); - table->advanceHeightMax = sfnt_get_short(sfont); /* ushort ? */ + table->advanceHeightMax = sfnt_get_short(sfont); table->minTopSideBearing = sfnt_get_short(sfont); table->minBottomSideBearing = sfnt_get_short(sfont); table->yMaxExtent = sfnt_get_short(sfont); @@ -261,34 +229,26 @@ struct tt_vhea_table *tt_read_vhea_table(sfnt * sfont) (table->reserved)[i] = sfnt_get_short(sfont); } table->numOfLongVerMetrics = sfnt_get_ushort(sfont); - return table; } - struct tt_VORG_table *tt_read_VORG_table(sfnt * sfont) { struct tt_VORG_table *vorg; ULONG offset; USHORT i; - offset = sfnt_find_table_pos(sfont, "VORG"); - if (offset > 0) { vorg = NEW(1, struct tt_VORG_table); - sfnt_locate_table(sfont, "VORG"); if (sfnt_get_ushort(sfont) != 1 || sfnt_get_ushort(sfont) != 0) normal_error("ttf","unsupported VORG version"); - vorg->defaultVertOriginY = sfnt_get_short(sfont); vorg->numVertOriginYMetrics = sfnt_get_ushort(sfont); - vorg->vertOriginYMetrics = NEW(vorg->numVertOriginYMetrics, - struct tt_vertOriginYMetrics); - /* - * The vertOriginYMetrics array must be sorted in increasing - * glyphIndex order. - */ + vorg->vertOriginYMetrics = NEW(vorg->numVertOriginYMetrics, struct tt_vertOriginYMetrics); + /*tex + The |vertOriginYMetrics| array must be sorted in increasing |glyphIndex| order. + */ for (i = 0; i < vorg->numVertOriginYMetrics; i++) { vorg->vertOriginYMetrics[i].glyphIndex = sfnt_get_ushort(sfont); vorg->vertOriginYMetrics[i].vertOriginY = sfnt_get_short(sfont); @@ -296,22 +256,20 @@ struct tt_VORG_table *tt_read_VORG_table(sfnt * sfont) } else { vorg = NULL; } - return vorg; } +/*tex -@ hmtx and vmtx + Reading and writing |hmtx| and |vmtx| depends on other tables, like |maxp|, + |hhea| and |vhea|. -Reading/writing hmtx and vmtx depend on other tables, maxp and hhea/vhea. +*/ -@c -struct tt_longMetrics *tt_read_longMetrics(sfnt * sfont, USHORT numGlyphs, - USHORT numLongMetrics) +struct tt_longMetrics *tt_read_longMetrics(sfnt * sfont, USHORT numGlyphs, USHORT numLongMetrics) { struct tt_longMetrics *m; USHORT gid, last_adv = 0; - m = NEW(numGlyphs, struct tt_longMetrics); for (gid = 0; gid < numGlyphs; gid++) { if (gid < numLongMetrics) @@ -319,26 +277,23 @@ struct tt_longMetrics *tt_read_longMetrics(sfnt * sfont, USHORT numGlyphs, m[gid].sideBearing = sfnt_get_short(sfont); m[gid].advance = last_adv; } - return m; } -@ OS/2 table +/*tex + + The |OS/2| table may not exist. + +*/ -this table may not exist -@c struct tt_os2__table *tt_read_os2__table(sfnt * sfont) { struct tt_os2__table *table = NULL; int i; - if (sfnt_find_table_pos(sfont, "OS/2") == 0) return NULL; - sfnt_locate_table(sfont, "OS/2"); - table = NEW(1, struct tt_os2__table); - table->version = sfnt_get_ushort(sfont); table->xAvgCharWidth = sfnt_get_short(sfont); table->usWeightClass = sfnt_get_ushort(sfont); @@ -382,37 +337,31 @@ struct tt_os2__table *tt_read_os2__table(sfnt * sfont) table->usBreakChar = sfnt_get_ushort(sfont); table->usMaxContext = sfnt_get_ushort(sfont); } - return table; } -USHORT -tt_get_name(sfnt * sfont, char *dest, USHORT destlen, +USHORT tt_get_name(sfnt * sfont, char *dest, USHORT destlen, USHORT plat_id, USHORT enco_id, USHORT lang_id, USHORT name_id) { USHORT length = 0; USHORT num_names, string_offset; ULONG name_offset; int i; - name_offset = sfnt_locate_table(sfont, "name"); - if (sfnt_get_ushort(sfont)) normal_error("ttf","expecting zero"); - num_names = sfnt_get_ushort(sfont); string_offset = sfnt_get_ushort(sfont); for (i = 0; i < num_names; i++) { USHORT p_id, e_id, n_id, l_id; USHORT offset; - p_id = sfnt_get_ushort(sfont); e_id = sfnt_get_ushort(sfont); l_id = sfnt_get_ushort(sfont); n_id = sfnt_get_ushort(sfont); length = sfnt_get_ushort(sfont); offset = sfnt_get_ushort(sfont); - /* language ID value 0xffffu for `accept any language ID' */ + /*tex The language |ID| value |0xffffu| stands for ``accept any language ID''. */ if ((p_id == plat_id) && (e_id == enco_id) && (lang_id == 0xffffu || l_id == lang_id) && (n_id == name_id)) { if (length > destlen - 1) { @@ -428,33 +377,28 @@ tt_get_name(sfnt * sfont, char *dest, USHORT destlen, if (i == num_names) { length = 0; } - return length; } USHORT tt_get_ps_fontname(sfnt * sfont, char *dest, USHORT destlen) { USHORT namelen = 0; - - /* First try Mac-Roman PS name and then Win-Unicode PS name */ + /*tex First try Mac-Roman PS name and then Win-Unicode PS name. */ if ((namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0, 6)) != 0 || (namelen = tt_get_name(sfont, dest, destlen, 3, 1, 0x409u, 6)) != 0 || (namelen = tt_get_name(sfont, dest, destlen, 3, 5, 0x412u, 6)) != 0) return namelen; - normal_warning("ttf","no valid PostScript name available"); - /* - Wrokaround for some bad TTfonts: - Language ID value 0xffffu for `accept any language ID' - */ + /*tex + This is a workaround for some bad TTfonts: the language ID value |0xffffu| + indicates ``accept any language ID''. + */ if ((namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0xffffu, 6)) == 0) { - /* - Finally falling back to Mac Roman name field. - Warning: Some bad Japanese TTfonts using SJIS encoded string in the - Mac Roman name field. - */ + /*tex + Finally we're falling back to Mac Roman name field. Some bad Japanese TTfonts + using SJIS encoded string in the Mac Roman name field. + */ namelen = tt_get_name(sfont, dest, destlen, 1, 0, 0, 1); } - return namelen; } diff --git a/Build/source/texk/web2c/luatexdir/font/vfovf.c b/Build/source/texk/web2c/luatexdir/font/vfovf.c new file mode 100644 index 00000000000..e1fdb903e42 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/font/vfovf.c @@ -0,0 +1,1444 @@ +/* + +Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> +Copyright 2006-2013 Taco Hoekwater <taco@luatex.org> + +This file is part of LuaTeX. + +LuaTeX 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. + +LuaTeX 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 Lesser General Public License for more details. + +You should have received a copy of the GNU General Public License along +with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +*/ + +#include "ptexlib.h" + +#define font_max 5000 + +/* The instruction set: */ + +#define set_char_0 0 /* typeset character 0 and move right */ +#define set1 128 /* typeset a character and move right */ +#define set2 129 /* typeset a character and move right */ +#define set3 130 /* typeset a character and move right */ +#define set4 131 /* typeset a character and move right */ +#define set_rule 132 /* typeset a rule and move right */ +#define put1 133 /* typeset a character without moving */ +#define put2 134 /* typeset a character without moving */ +#define put3 135 /* typeset a character without moving */ +#define put4 136 /* typeset a character without moving */ +#define put_rule 137 /* typeset a rule */ +#define nop 138 /* no operation */ +#define bop 139 /* beginning of page */ +#define eop 140 /* ending of page */ +#define push 141 /* save the current positions */ +#define pop 142 /* restore previous positions */ +#define right1 143 /* move right */ +#define right2 144 /* move right */ +#define right3 145 /* move right */ +#define right4 146 /* move right, 4 bytes */ +#define w0 147 /* move right by |w| */ +#define w1 148 /* move right and set |w| */ +#define w2 149 /* move right and set |w| */ +#define w3 150 /* move right and set |w| */ +#define w4 151 /* move right and set |w| */ +#define x0 152 /* move right by |x| */ +#define x1 153 /* move right and set |x| */ +#define x2 154 /* move right and set |x| */ +#define x3 155 /* move right and set |x| */ +#define x4 156 /* move right and set |x| */ +#define down1 157 /* move down */ +#define down2 158 /* move down */ +#define down3 159 /* move down */ +#define down4 160 /* move down, 4 bytes */ +#define y0 161 /* move down by |y| */ +#define y1 162 /* move down and set |y| */ +#define y2 163 /* move down and set |y| */ +#define y3 164 /* move down and set |y| */ +#define y4 165 /* move down and set |y| */ +#define z0 166 /* move down by |z| */ +#define z1 167 /* move down and set |z| */ +#define z2 168 /* move down and set |z| */ +#define z3 169 /* move down and set |z| */ +#define z4 170 /* move down and set |z| */ +#define fnt_num_0 171 /* set current font to 0 */ +#define fnt1 235 /* set current font */ +#define fnt2 236 /* set current font */ +#define fnt3 237 /* set current font */ +#define fnt4 238 /* set current font */ +#define xxx1 239 /* extension to DVI primitives */ +#define xxx2 240 /* extension to DVI primitives */ +#define xxx3 241 /* extension to DVI primitives */ +#define xxx4 242 /* potentially long extension to DVI primitives */ +#define fnt_def1 243 /* define the meaning of a font number */ +#define pre 247 /* preamble */ +#define post 248 /* postamble beginning */ +#define post_post 249 /* postamble ending */ +#define yyy1 250 /* PDF literal text */ +#define yyy2 251 /* PDF literal text */ +#define yyy3 252 /* PDF literal text */ +#define yyy4 253 /* PDF literal text */ + +#define null_font 0 + +#define long_char 242 /* |VF| command for general character packet */ + +#define vf_id 202 /* identifies \VF\ files */ + +/*tex + + Quit |VF| processing with an error message. + +*/ + +#define bad_vf(a) { \ + xfree(vf_buffer); \ + print_nlp(); \ + formatted_warning("virtual font","file '%s', %s, font will be ignored",font_name(f),a); \ + print_ln(); \ + return; \ +} + +#define lua_bad_vf(a) { \ + xfree(vf_buffer); \ + lua_settop(L,s_top); \ + lua_pushnil(L); \ + lua_pushstring(L,a); \ + return 2; \ +} + +#define tmp_b0 tmp_w.qqqq.b0 +#define tmp_b1 tmp_w.qqqq.b1 +#define tmp_b2 tmp_w.qqqq.b2 +#define tmp_b3 tmp_w.qqqq.b3 +#define tmp_int tmp_w.cint + +/*tex \DVI\ files shouldn't |push| beyond this depth: */ + +#define vf_stack_size 100 + +/*tex An index into the stack: */ + +typedef unsigned char vf_stack_index; + +typedef struct vf_stack_record { + scaled stack_w, stack_x, stack_y, stack_z; +} vf_stack_record; + +/*tex Get a byte from the \VF\ file: */ + +#define vf_byte(a) \ +{ \ + eight_bits vf_tmp_b; \ + if (vf_cur >= vf_size) { \ + normal_error("virtual font","unexpected eof"); \ + } \ + vf_tmp_b = vf_buffer[vf_cur++]; \ + a = vf_tmp_b; \ +} + +#define vf_replace_z() \ +{ \ + vf_alpha = 16; \ + while (vf_z >= 040000000) { \ + vf_z = vf_z / 2; \ + vf_alpha += vf_alpha; \ + } \ + /*tex |vf_beta = (char)(256 / vf_alpha)| */ \ + vf_alpha = (vf_alpha * vf_z); \ +} + +/*tex + + Read |k| bytes as an integer from \VF\ file. Beware: the |vf_read| macro + differs from |vf_read| in |vftovp.web| for 1 upto 3 byte words. + +*/ + +#define vf_read(k, l) \ +{ \ + int itmp = 0, dtmp = (int)(k), jtmp = 0; \ + while (dtmp > 0) { \ + vf_byte(jtmp); \ + if ((dtmp == (int) k) && jtmp > 127) \ + jtmp = jtmp - 256; \ + itmp = itmp * 256 + jtmp; \ + decr(dtmp); \ + } \ + l = itmp; \ +} + +#define vf_read_u(k, l) \ +{ \ + int dtmp = (int)(k); \ + unsigned int itmp = 0, jtmp = 0; \ + while (dtmp-- > 0) { \ + vf_byte(jtmp); \ + itmp = itmp * 256 + jtmp; \ + } \ + l = itmp; \ +} + +void pdf_check_vf(internal_font_number f) +{ + if (font_type(f) == virtual_font_type) + normal_error("font", "command cannot be used with virtual font"); +} + +static void vf_local_font_warning(internal_font_number f, internal_font_number k, const char *s, int a, int b) +{ + print_nlp(); + tprint(s); + tprint(" in local font "); + tprint(font_name(k)); + tprint(" ("); + print_int(b); + tprint(" != "); + print_int(a); + tprint(") in virtual font "); + tprint(font_name(f)); + tprint(".vf ignored."); +} + +/*tex Process a local font in the \VF\ file. */ + +int level = 0; + +static internal_font_number vf_def_font(internal_font_number f, unsigned char *vf_buffer, int *vf_cr) +{ + internal_font_number k; + str_number s; + char *st; + scaled ds, fs; + four_quarters cs; + /*tex The accumulator: */ + memory_word tmp_w; + int junk; + unsigned int checksum; + cs.b0 = vf_buffer[(*vf_cr)]; + cs.b1 = vf_buffer[(*vf_cr) + 1]; + cs.b2 = vf_buffer[(*vf_cr) + 2]; + cs.b3 = vf_buffer[(*vf_cr) + 3]; + (*vf_cr) += 4; + checksum = (unsigned) (cs.b0 * 256 * 256 * 256 + cs.b1 * 256 * 256 + cs.b2 * 256 + cs.b3); + k = vf_buffer[(*vf_cr)]; + (*vf_cr)++; + if (k > 127) + k -= 256; + k = k * 256 + vf_buffer[(*vf_cr)]; + (*vf_cr)++; + k = k * 256 + vf_buffer[(*vf_cr)]; + (*vf_cr)++; + k = k * 256 + vf_buffer[(*vf_cr)]; + (*vf_cr)++; + fs = store_scaled_f(k, font_size(f)); + k = vf_buffer[(*vf_cr)]; + (*vf_cr)++; + if (k > 127) + k -= 256; + k = k * 256 + vf_buffer[(*vf_cr)]; + (*vf_cr)++; + k = k * 256 + vf_buffer[(*vf_cr)]; + (*vf_cr)++; + k = k * 256 + vf_buffer[(*vf_cr)]; + (*vf_cr)++; + ds = k / 16; + tmp_b0 = vf_buffer[(*vf_cr)]; + (*vf_cr)++; + tmp_b1 = vf_buffer[(*vf_cr)]; + (*vf_cr)++; + while (tmp_b0 > 0) { + /*tex Skip the font path. */ + tmp_b0--; + (*vf_cr)++; + } + str_room((unsigned) tmp_b1); + while (tmp_b1 > 0) { + tmp_b1--; + junk = vf_buffer[(*vf_cr)]; + (*vf_cr)++; + append_char(junk); + } + if (level > 5) { + normal_warning("vf","quitting at recurse depth > 5"); + k = f ; + } else if ((level > 1) && (fs > 65536*1024)) { + normal_warning("vf","quitting when recursing at size > 65536*1024"); + k = f ; + } else { + level += 1 ; + s = make_string(); + st = makecstring(s); + k = tfm_lookup(st, fs); + if (k == null_font) + k = read_font_info(null_cs, st, fs, -1); + free(st); + level -= 1 ; + if (k != null_font) { + if (checksum != 0 && font_checksum(k) != 0 + && checksum != font_checksum(k)) + vf_local_font_warning(f, k, "checksum mismatch", (int) checksum, (int) font_checksum(k)); + if (ds != font_dsize(k)) + vf_local_font_warning(f, k, "design size mismatch", ds, font_dsize(k)); + } + } + return k; +} + +static int open_vf_file(const char *fn, unsigned char **vbuffer, int *vsize) +{ + /*tex Was the callback successful? */ + boolean res; + int callback_id; + /*tex Was |vf_file| successfully read? */ + boolean file_read = false; + FILE *vf_file; + const char *fname = luatex_find_file(fn, find_vf_file_callback); + if (fname == NULL || strlen(fname) == 0) { + return 0; + } + + callback_id = callback_defined(read_vf_file_callback); + if (callback_id > 0) { + res = run_callback(callback_id, "S->bSd", fname, + &file_read, vbuffer, vsize); + if (res && file_read && (*vsize > 0)) { + return 1; + } + if (!file_read) + return 0; + } else { + if (luatex_open_input + (&(vf_file), fname, kpse_ovf_format, FOPEN_RBIN_MODE, false) + || luatex_open_input(&(vf_file), fname, kpse_vf_format, FOPEN_RBIN_MODE, false)) { + res = read_vf_file(vf_file, vbuffer, vsize); + close_file(vf_file); + if (res) { + return 1; + } + } else { + return 0; + } + } + return 0; +} + +/*tex + + The |do_vf| procedure attempts to read the \VF\ file for a font, and sets + |font_type()| to |real_font_type| if the \VF\ file could not be found or + loaded, otherwise sets |font_type()| to |virtual_font_type|. At this time, + |tmp_f| is the internal font number of the current \TFM\ font. To process + font definitions in virtual font we call |vf_def_font|. + +*/ + +#define append_packet(k) vpackets[vf_np++] = (eight_bits)(k) + +/*tex + + Life is easier if all internal font commands are |fnt4| and all character + commands are |set4| or |put4|. + +*/ + +#define append_fnt_set(k) \ +{ \ + assert(k > 0); \ + append_packet(packet_font_code); \ + append_four(k); \ +} + +#define append_four(k) \ +{ \ + append_packet((k & 0xFF000000) >> 24); \ + append_packet((k & 0x00FF0000) >> 16); \ + append_packet((k & 0x0000FF00) >> 8); \ + append_packet((k & 0x000000FF)); \ +} + +/*tex Some of these things happen twice, adding a define is simplest. */ + +#define test_checksum() { vf_byte(tmp_b0); vf_byte(tmp_b1); \ + vf_byte(tmp_b2); vf_byte(tmp_b3); \ + if (((tmp_b0 != 0) || (tmp_b1 != 0) || (tmp_b2 != 0) || (tmp_b3 != 0)) && \ + ((font_check_0(f) != 0) || (font_check_1(f) != 0) || \ + (font_check_2(f) != 0) || (font_check_3(f) != 0)) && \ + ((tmp_b0 != font_check_0(f)) || (tmp_b1 != font_check_1(f)) || \ + (tmp_b2 != font_check_2(f)) || (tmp_b3 != font_check_3(f)))) { \ + print_nlp(); \ + tprint("checksum mismatch in font "); \ + tprint(font_name(f)); \ + tprint(".vf ignored "); } } + +#define test_dsize() \ +{ \ + int read_tmp; \ + vf_read(4, read_tmp); \ + if ((read_tmp / 16) != font_dsize(f)) { \ + print_nlp(); \ + tprint("design size mismatch in font "); \ + tprint(font_name(f)); \ + tprint(".vf ignored"); \ + } \ +} + +static int count_packet_bytes(eight_bits * vf_buf, int cur_bute, int count) +{ + unsigned k = 0; + int ff = 0; + int acc = 0; + unsigned int cmd = 0; + unsigned int d = 0; + while (k < (unsigned) count) { + cmd = vf_buf[cur_bute + (int) k]; + k++; + if (cmd < set1) { + if (ff == 0) { + ff = 1; + acc += 5; + } + acc += 5; + } else if ((fnt_num_0 <= cmd) && (cmd <= fnt_num_0 + 63)) { + ff = 1; + acc += 5; + } else { + switch (cmd) { + case fnt1: + acc += 5; + k += 1; + ff = 1; + break; + case fnt2: + acc += 5; + k += 2; + ff = 1; + break; + case fnt3: + acc += 5; + k += 3; + ff = 1; + break; + case fnt4: + acc += 5; + k += 4; + ff = 1; + break; + case set_rule: + acc += 9; + k += 8; + break; + case put_rule: + acc += 11; + k += 8; + break; + case set1: + acc += 5; + k += 1; + if (ff == 0) { + ff = 1; + acc += 5; + } + break; + case set2: + acc += 5; + k += 2; + if (ff == 0) { + ff = 1; + acc += 5; + } + break; + case set3: + acc += 5; + k += 3; + if (ff == 0) { + ff = 1; + acc += 5; + } + break; + case set4: + acc += 5; + k += 4; + if (ff == 0) { + ff = 1; + acc += 5; + } + break; + case put1: + acc += 7; + k += 1; + if (ff == 0) { + ff = 1; + acc += 5; + } + break; + case put2: + acc += 7; + k += 2; + if (ff == 0) { + ff = 1; + acc += 5; + } + break; + case put3: + acc += 7; + k += 3; + if (ff == 0) { + ff = 1; + acc += 5; + } + break; + case put4: + acc += 7; + k += 4; + if (ff == 0) { + ff = 1; + acc += 5; + } + break; + case right1: + acc += 5; + k += 1; + break; + case right2: + acc += 5; + k += 2; + break; + case right3: + acc += 5; + k += 3; + break; + case right4: + acc += 5; + k += 4; + break; + case w1: + acc += 5; + k += 1; + break; + case w2: + acc += 5; + k += 2; + break; + case w3: + acc += 5; + k += 3; + break; + case w4: + acc += 5; + k += 4; + break; + case x1: + acc += 5; + k += 1; + break; + case x2: + acc += 5; + k += 2; + break; + case x3: + acc += 5; + k += 3; + break; + case x4: + acc += 5; + k += 4; + break; + case down1: + acc += 5; + k += 1; + break; + case down2: + acc += 5; + k += 2; + break; + case down3: + acc += 5; + k += 3; + break; + case down4: + acc += 5; + k += 4; + break; + case y1: + acc += 5; + k += 1; + break; + case y2: + acc += 5; + k += 2; + break; + case y3: + acc += 5; + k += 3; + break; + case y4: + acc += 5; + k += 4; + break; + case z1: + acc += 5; + k += 1; + break; + case z2: + acc += 5; + k += 2; + break; + case z3: + acc += 5; + k += 3; + break; + case z4: + acc += 5; + k += 4; + break; + case xxx1: + d = vf_buf[cur_bute + (int) k]; + k++; + k += d; + acc += 5 + (int) d; + break; + case xxx2: + d = vf_buf[cur_bute + (int) k]; + k++; + d = d * 256 + vf_buf[cur_bute + (int) k]; + k++; + k += d; + acc += 5 + (int) d; + break; + case xxx3: + d = vf_buf[cur_bute + (int) k]; + k++; + d = d * 256 + vf_buf[cur_bute + (int) k]; + k++; + d = d * 256 + vf_buf[cur_bute + (int) k]; + k++; + k += d; + acc += 5 + (int) d; + break; + case xxx4: + d = vf_buf[cur_bute + (int) k]; + k++; + d = d * 256 + vf_buf[cur_bute + (int) k]; + k++; + d = d * 256 + vf_buf[cur_bute + (int) k]; + k++; + d = d * 256 + vf_buf[cur_bute + (int) k]; + k++; + k += d; + acc += 5 + (int) d; + break; + case w0: + acc += 5; + break; + case x0: + acc += 5; + break; + case y0: + acc += 5; + break; + case z0: + acc += 5; + break; + case nop: + break; + case push: + acc += 1; + break; + case pop: + acc += 1; + break; + } + } + } + return (acc + 1); +} + +void do_vf(internal_font_number f) +{ + int k, i; + unsigned cmd, n; + scaled x, y, w, z, h, v; + int cc, cmd_length; + unsigned packet_length; + charinfo *co; + scaled tfm_width; + int save_cur_byte; + vf_stack_index stack_level; + /*tex multiplier */ + int vf_z; + /*tex correction for negative values */ + int vf_alpha; + int vf_np; + eight_bits *vpackets; + /*tex accumulator */ + memory_word tmp_w; + vf_stack_record vf_stack[256]; + int junk; + unsigned utmp; + unsigned char *vf_buffer; + int vf_size; + int vf_cur; + /*tex external font ids */ + unsigned *vf_local_fnts = NULL; + /*tex internal font ids */ + unsigned *vf_real_fnts = NULL; + /*tex local font counter */ + unsigned vf_nf = 0; + if (font_type(f) != unknown_font_type) + return; + set_font_type(f, real_font_type); + stack_level = 0; + /*tex Open |vf_file|, return if not found */ + vf_cur = 0; + vf_buffer = NULL; + vf_size = 0; + if (!open_vf_file(font_name(f), &vf_buffer, &vf_size)) + return; + /*tex Process the preamble */ + set_font_type(f, virtual_font_type); + vf_byte(k); + if (k != pre) + bad_vf("PRE command expected"); + vf_byte(k); + if (k != vf_id) + bad_vf("wrong id byte"); + vf_byte(cmd_length); + for (k = 1; k <= cmd_length; k++) + vf_byte(junk); + test_checksum(); + test_dsize(); + vf_z = font_size(f); + vf_replace_z(); + /*tex Process the font definitions; scan forward to find the number of internal fonts. */ + vf_nf = 0; + save_cur_byte = vf_cur; + vf_byte(cmd); + while ((cmd >= fnt_def1) && (cmd <= (fnt_def1 + 3))) { + vf_read_u((cmd - fnt_def1 + 1), utmp); + vf_read(4, junk); + vf_read(4, junk); + vf_read(4, junk); + vf_byte(k); + vf_byte(junk); + k += junk; + while (k-- > 0) { + vf_byte(junk); + } + incr(vf_nf); + vf_byte(cmd); + } + vf_cur = save_cur_byte; + vf_byte(cmd); + /*tex Do a |malloc| and fill the local font arrays. */ + if (vf_nf > 0) { + unsigned ii = (unsigned) ((unsigned) vf_nf * sizeof(int)); + vf_local_fnts = xmalloc(ii); + memset(vf_local_fnts, 0, ii); + vf_real_fnts = xmalloc(ii); + memset(vf_real_fnts, 0, ii); + vf_nf = 0; + while ((cmd >= fnt_def1) && (cmd <= (fnt_def1 + 3))) { + vf_read_u((cmd - fnt_def1 + 1), vf_local_fnts[vf_nf]); + vf_real_fnts[vf_nf] = (unsigned) vf_def_font(f, vf_buffer, &vf_cur); + incr(vf_nf); + vf_byte(cmd); + } + } + while (cmd <= long_char) { + /*tex Build a character packet. */ + vf_np = 0; + if (cmd == long_char) { + vf_read_u(4, packet_length); + vf_read_u(4, utmp); + cc = (int) utmp; + if (!char_exists(f, cc)) { + bad_vf("invalid character code"); + } + vf_read(4, k); + tfm_width = store_scaled_f(k, font_size(f)); + } else { + packet_length = cmd; + vf_byte(cc); + if (!char_exists(f, cc)) { + bad_vf("invalid character code"); + } + vf_read_u(3, utmp); + /*tex cf. |vftovp.web|, line 1028 */ + k = (int) utmp; + tfm_width = store_scaled_f(k, font_size(f)); + } + if (tfm_width != char_width(f, cc)) { + if (tfm_width != char_width(f, cc)) { + print_nlp(); + tprint("character width mismatch in font "); + tprint(font_name(f)); + tprint(".vf ignored"); + } + } + k = count_packet_bytes(vf_buffer, vf_cur, (int) packet_length); + /*tex We need one extra extra for |packet_end|. */ + vpackets = xmalloc((unsigned) (k + 1)); + co = get_charinfo(f, cc); + k = 0; + w = 0; + x = 0; + y = 0; + z = 0; + while (packet_length > 0) { + vf_byte(cmd); + decr(packet_length); + if (cmd < set1) { + if (k == 0) { + k = (int) vf_real_fnts[0]; + append_fnt_set(k); + } + append_packet(packet_char_code); + append_four(cmd); + cmd_length = 0; + cmd = nop; + } else if (((fnt_num_0 <= cmd) && (cmd <= fnt_num_0 + 63)) || + ((fnt1 <= cmd) && (cmd <= fnt1 + 3))) { + if (cmd >= fnt1) { + vf_read_u((cmd - fnt1 + 1), utmp); + k = (int) utmp; + packet_length -= (cmd - fnt1 + 1); + } else { + k = (int) cmd - fnt_num_0; + } + /*tex Change from local to external font id. */ + n = 0; + while ((n < vf_nf) && (vf_local_fnts[n] != (unsigned) k)) + n++; + if (n == vf_nf) + bad_vf("undefined local font"); + k = (int) vf_real_fnts[n]; + append_fnt_set(k); + cmd_length = 0; + cmd = nop; + } else { + switch (cmd) { + case set_rule: + vf_read(4, h); + vf_read(4, v); + append_packet(packet_rule_code); + append_four(h); + append_four(v); + packet_length -= 8; + break; + case put_rule: + vf_read(4, h); + vf_read(4, v); + append_packet(packet_push_code); + append_packet(packet_rule_code); + append_four(h); + append_four(v); + append_packet(packet_pop_code); + packet_length -= 8; + break; + case set1: + case set2: + case set3: + case set4: + if (k == 0) { + k = (int) vf_real_fnts[0]; + append_fnt_set(k); + } + vf_read_u((cmd - set1 + 1), utmp); + i = (int) utmp; + append_packet(packet_char_code); + append_four(i); + packet_length -= (cmd - set1 + 1); + break; + case put1: + case put2: + case put3: + case put4: + if (k == 0) { + k = (int) vf_real_fnts[0]; + append_fnt_set(k); + } + vf_read_u((cmd - put1 + 1), utmp); + i = (int) utmp; + append_packet(packet_push_code); + append_packet(packet_char_code); + append_four(i); + append_packet(packet_pop_code); + packet_length -= (cmd - put1 + 1); + break; + case right1: + case right2: + case right3: + case right4: + vf_read((cmd - right1 + 1), i); + append_packet(packet_right_code); + append_four(i); + packet_length -= (cmd - right1 + 1); + break; + case w1: + case w2: + case w3: + case w4: + vf_read((cmd - w1 + 1), w); + append_packet(packet_right_code); + append_four(w); + packet_length -= (cmd - w1 + 1); + break; + case x1: + case x2: + case x3: + case x4: + vf_read((cmd - x1 + 1), x); + append_packet(packet_right_code); + append_four(x); + packet_length -= (cmd - x1 + 1); + break; + case down1: + case down2: + case down3: + case down4: + vf_read((cmd - down1 + 1), i); + append_packet(packet_down_code); + append_four(i); + packet_length -= (cmd - down1 + 1); + break; + case y1: + case y2: + case y3: + case y4: + vf_read((cmd - y1 + 1), y); + append_packet(packet_down_code); + append_four(y); + packet_length -= (cmd - y1 + 1); + break; + case z1: + case z2: + case z3: + case z4: + vf_read((cmd - z1 + 1), z); + append_packet(packet_down_code); + append_four(z); + packet_length -= (cmd - z1 + 1); + break; + case xxx1: + case xxx2: + case xxx3: + case xxx4: + vf_read_u((cmd - xxx1 + 1), utmp); + cmd_length = (int) utmp; + packet_length -= (cmd - xxx1 + 1); + if (cmd_length <= 0) + bad_vf("special of negative length"); + packet_length -= (unsigned) cmd_length; + append_packet(packet_special_code); + append_four(cmd_length); + while (cmd_length > 0) { + cmd_length--; + vf_byte(i); + append_packet(i); + } + break; + case w0: + append_packet(packet_right_code); + append_four(w); + break; + case x0: + append_packet(packet_right_code); + append_four(x); + break; + case y0: + append_packet(packet_down_code); + append_four(y); + break; + case z0: + append_packet(packet_down_code); + append_four(z); + break; + case nop: + break; + case push: + if (stack_level == vf_stack_size) { + overflow("virtual font stack size", vf_stack_size); + } else { + vf_stack[stack_level].stack_w = w; + vf_stack[stack_level].stack_x = x; + vf_stack[stack_level].stack_y = y; + vf_stack[stack_level].stack_z = z; + incr(stack_level); + append_packet(packet_push_code); + } + break; + case pop: + if (stack_level == 0) { + bad_vf("more POPs than PUSHs in character"); + } else { + decr(stack_level); + w = vf_stack[stack_level].stack_w; + x = vf_stack[stack_level].stack_x; + y = vf_stack[stack_level].stack_y; + z = vf_stack[stack_level].stack_z; + append_packet(packet_pop_code); + } + break; + default: + bad_vf("improver DVI command"); + } + } + } + /*tex Signal end of packet. */ + append_packet(packet_end_code); + if (stack_level != 0) + bad_vf("more PUSHs than POPs in character packet"); + if (packet_length != 0) + bad_vf("invalid packet length or DVI command in packet"); + /*tex Store the packet being built. */ + set_charinfo_packets(co, vpackets); + vf_byte(cmd); + } + if (cmd != post) + bad_vf("POST command expected"); + + xfree(vf_buffer); +} + +#define make_command0(N,K) { \ + lua_newtable(L); \ + lua_pushstring(L, N); \ + lua_rawseti(L,-2, 1); \ + lua_rawseti(L,-2, K); \ + K++; } + +#define make_command1(N,V,K) { \ + lua_newtable(L); \ + lua_pushstring(L, N); \ + lua_rawseti(L,-2, 1); \ + lua_pushinteger(L, V); \ + lua_rawseti(L,-2, 2); \ + lua_rawseti(L,-2, K); \ + K++; } + +#define make_command2(N,V,W,K) { \ + lua_newtable(L); \ + lua_pushstring(L, N); \ + lua_rawseti(L,-2, 1); \ + lua_pushinteger(L, V); \ + lua_rawseti(L,-2, 2); \ + lua_pushinteger(L, W); \ + lua_rawseti(L,-2, 3); \ + lua_rawseti(L,-2, K); \ + K++; } + +#define make_commands(N,S,V,K) { \ + lua_newtable(L); \ + lua_pushstring(L, N); \ + lua_rawseti(L,-2, 1); \ + lua_pushlstring(L, S, V); \ + lua_rawseti(L,-2, 2); \ + lua_rawseti(L,-2, K); \ + K++; } + +int make_vf_table(lua_State * L, const char *cnom, scaled atsize) +{ + int cmd, k, i; + int cc; + unsigned cmd_length, packet_length; + scaled tfm_width; + vf_stack_index stack_level; + /*tex multiplier */ + int vf_z; + /*tex correction for negative values */ + int vf_alpha; + eight_bits *s; + scaled h, v; + scaled w, x, y, z; + /*tex \LUA\ stack */ + int s_top; + /*tex local font counter */ + int vf_nf; + scaled ds, fs; + four_quarters cs; + /*tex accumulator */ + memory_word tmp_w; + vf_stack_record vf_stack[256]; + unsigned char *vf_buffer; + int vf_size; + int vf_cur; + unsigned utmp; + stack_level = 0; + /*tex Open |vf_file|, return if not found. */ + vf_cur = 0; + vf_buffer = NULL; + vf_size = 0; + if (!open_vf_file(cnom, &vf_buffer, &vf_size)) { + lua_pushnil(L); + return 1; + } + /*tex Start by creating a table. */ + s_top = lua_gettop(L); + lua_newtable(L); + /*tex Process the preamble. */ + vf_byte(k); + if (k != pre) + lua_bad_vf("PRE command expected"); + vf_byte(k); + if (k != vf_id) + lua_bad_vf("wrong id byte"); + vf_byte(cmd_length); + s = xmalloc(cmd_length); + for (k = 1; k <= (int) cmd_length; k++) + vf_byte(s[(k - 1)]); + lua_pushlstring(L, (char *) s, (size_t) cmd_length); + free(s); + lua_setfield(L, -2, "header"); + vf_byte(cs.b0); + vf_byte(cs.b1); + vf_byte(cs.b2); + vf_byte(cs.b3); + lua_pushinteger(L, (lua_Number) ((cs.b0 << 24) + (cs.b1 << 16) + (cs.b2 << 8) + cs.b3)); + lua_setfield(L, -2, "checksum"); + vf_read(4, k); + ds = k / 16; + lua_pushinteger(L, ds); + lua_setfield(L, -2, "designsize"); + lua_pushstring(L, cnom); + lua_setfield(L, -2, "name"); + lua_pushinteger(L, atsize); + lua_setfield(L, -2, "size"); + vf_z = atsize; + vf_replace_z(); + /*tex Process the font definitions. */ + vf_byte(cmd); + lua_newtable(L); + i = 1; + while ((cmd >= fnt_def1) && (cmd <= fnt_def1 + 3)) { + lua_newtable(L); + vf_read_u((cmd - fnt_def1 + 1), utmp); + vf_nf = (int) utmp; + vf_nf++; + /*tex Add a checksum. */ + vf_byte(cs.b0); + vf_byte(cs.b1); + vf_byte(cs.b2); + vf_byte(cs.b3); + vf_read(4, k); + fs = store_scaled_f(k, atsize); + lua_pushstring(L, "size"); + lua_pushinteger(L, fs); + lua_rawset(L, -3); + vf_read(4, k); + /*tex |dsize| is not used */ + ds = k / 16; + vf_byte(tmp_b0); + vf_byte(tmp_b1); + /*tex Skip the font path. */ + while (tmp_b0 > 0) { + tmp_b0--; + vf_byte(k); + } + s = xmalloc((unsigned) (tmp_b1 + 1)); + k = 0; + while (tmp_b1-- > 0) + vf_byte(s[k++]); + s[k] = 0; + lua_pushstring(L, "name"); + lua_pushstring(L, xstrdup((char *) s)); + free(s); + lua_rawset(L, -3); + lua_rawseti(L, -2, vf_nf); + i++; + vf_byte(cmd); + } + if (i > 1) { + lua_setfield(L, -2, "fonts"); + } else { + lua_pop(L, 1); + } + /*tex The table; with characters comes next. */ + lua_newtable(L); + while (cmd <= long_char) { + /*tex Build a character packet. */ + if (cmd == long_char) { + vf_read_u(4, packet_length); + vf_read_u(4, utmp); + cc = (int) utmp; + vf_read(4, tfm_width); + } else { + packet_length = (unsigned) cmd; + vf_byte(cc); + vf_read_u(3, utmp); + tfm_width = (int) utmp; + } + /*tex For this character entry. */ + lua_newtable(L); + lua_pushinteger(L, tfm_width); + lua_setfield(L, -2, "width"); + /*tex for |commands|: */ + lua_newtable(L); + k = 1; + vf_nf = 0; + w = 0; + x = 0; + y = 0; + z = 0; + while (packet_length > 0) { + vf_byte(cmd); + decr(packet_length); + if ((cmd >= set_char_0) && (cmd < set1)) { + if (vf_nf == 0) { + vf_nf = 1; + make_command1("font", vf_nf, k); + } + make_command1("char", cmd, k); + } else if (((fnt_num_0 <= cmd) && (cmd <= fnt_num_0 + 63)) || ((fnt1 <= cmd) && (cmd <= fnt1 + 3))) { + if (cmd >= fnt1) { + vf_read_u((cmd - fnt1 + 1), utmp); + vf_nf = (int) utmp; + vf_nf++; + packet_length -= (unsigned) (cmd - fnt1 + 1); + } else { + vf_nf = cmd - fnt_num_0 + 1; + } + make_command1("font", vf_nf, k); + } else { + switch (cmd) { + case set_rule: + vf_read(4, h); + vf_read(4, v); + make_command2("rule", store_scaled_f(h, atsize), + store_scaled_f(v, atsize), k); + packet_length -= 8; + break; + case put_rule: + vf_read(4, h); + vf_read(4, v); + make_command0("push", k); + make_command2("rule", store_scaled_f(h, atsize), + store_scaled_f(v, atsize), k); + make_command0("pop", k); + packet_length -= 8; + break; + case set1: + case set2: + case set3: + case set4: + if (vf_nf == 0) { + vf_nf = 1; + make_command1("font", vf_nf, k); + } + vf_read_u((cmd - set1 + 1), utmp); + i = (int) utmp; + make_command1("char", i, k); + packet_length -= (unsigned) (cmd - set1 + 1); + break; + case put1: + case put2: + case put3: + case put4: + if (vf_nf == 0) { + vf_nf = 1; + make_command1("font", vf_nf, k); + } + vf_read_u((cmd - put1 + 1), utmp); + i = (int) utmp; + make_command0("push", k); + make_command1("char", i, k); + make_command0("pop", k); + packet_length -= (unsigned) (cmd - put1 + 1); + break; + case right1: + case right2: + case right3: + case right4: + vf_read((cmd - right1 + 1), i); + make_command1("right", store_scaled_f(i, atsize), k); + packet_length -= (unsigned) (cmd - right1 + 1); + break; + case w1: + case w2: + case w3: + case w4: + vf_read((cmd - w1 + 1), w); + make_command1("right", store_scaled_f(w, atsize), k); + packet_length -= (unsigned) (cmd - w1 + 1); + break; + case x1: + case x2: + case x3: + case x4: + vf_read((cmd - x1 + 1), x); + make_command1("right", store_scaled_f(x, atsize), k); + packet_length -= (unsigned) (cmd - x1 + 1); + break; + case down1: + case down2: + case down3: + case down4: + vf_read((cmd - down1 + 1), i); + make_command1("down", store_scaled_f(i, atsize), k); + packet_length -= (unsigned) (cmd - down1 + 1); + break; + case y1: + case y2: + case y3: + case y4: + vf_read((cmd - y1 + 1), y); + make_command1("down", store_scaled_f(y, atsize), k); + packet_length -= (unsigned) (cmd - y1 + 1); + break; + case z1: + case z2: + case z3: + case z4: + vf_read((cmd - z1 + 1), z); + make_command1("down", store_scaled_f(z, atsize), k); + packet_length -= (unsigned) (cmd - z1 + 1); + break; + case xxx1: + case xxx2: + case xxx3: + case xxx4: + vf_read_u((cmd - xxx1 + 1), cmd_length); + packet_length -= (unsigned) (cmd - xxx1 + 1); + if (cmd_length <= 0) + lua_bad_vf("special of negative length"); + packet_length -= cmd_length; + s = xmalloc((cmd_length + 1)); + i = 0; + while (cmd_length > 0) { + cmd_length--; + vf_byte(s[i]); + i++; + } + s[i] = 0; + make_commands("special", xstrdup((char *) s), (size_t) i, k); + free(s); + break; + case w0: + make_command1("right", store_scaled_f(w, atsize), k); + break; + case x0: + make_command1("right", store_scaled_f(x, atsize), k); + break; + case y0: + make_command1("down", store_scaled_f(y, atsize), k); + break; + case z0: + make_command1("down", store_scaled_f(z, atsize), k); + break; + case nop: + break; + case push: + if (stack_level == vf_stack_size) { + overflow("virtual font stack size", vf_stack_size); + } else { + vf_stack[stack_level].stack_w = w; + vf_stack[stack_level].stack_x = x; + vf_stack[stack_level].stack_y = y; + vf_stack[stack_level].stack_z = z; + incr(stack_level); + make_command0("push", k); + } + break; + case pop: + if (stack_level == 0) { + lua_bad_vf("more POPs than PUSHs in character"); + } else { + decr(stack_level); + w = vf_stack[stack_level].stack_w; + x = vf_stack[stack_level].stack_x; + y = vf_stack[stack_level].stack_y; + z = vf_stack[stack_level].stack_z; + make_command0("pop", k); + } + break; + default: + lua_bad_vf("improver DVI command"); + } + } + } + /*tex Signal end of packet. */ + lua_setfield(L, -2, "commands"); + if (stack_level != 0) + lua_bad_vf("more PUSHs than POPs in character packet"); + if (packet_length != 0) + lua_bad_vf("invalid packet length or DVI command in packet"); + lua_rawseti(L, -2, cc); + vf_byte(cmd); + } + lua_setfield(L, -2, "characters"); + if (cmd != post) + lua_bad_vf("POST command expected"); + xfree(vf_buffer); + return 1; +} + +internal_font_number letter_space_font(internal_font_number f, int e, boolean nolig) +{ + internal_font_number k; + scaled w; + int c; + charinfo *co; + char *new_font_name; + /*tex Read a new font and expand the character widths. */ + k = copy_font(f); + if (nolig) { + /*tex Disable ligatures for letter-spaced fonts. */ + set_no_ligatures(k); + } + /*tex append e.g. |+100ls| to font name; |abs(e) <= 1000|. */ + new_font_name = xmalloc((unsigned) (strlen(font_name(k)) + 8)); + if (e > 0) { + sprintf(new_font_name, "%s+%ils", font_name(k), (int) e); + } else { + /*tex Minus from |%i|: */ + sprintf(new_font_name, "%s%ils", font_name(k), (int) e); + } + set_font_name(k, new_font_name); + /* Create the corresponding virtual font. */ + set_font_type(k, virtual_font_type); + for (c=font_bc(k);c<=font_ec(k);c++) { + if (quick_char_exists(k, c)) { + int half_w; + int vf_np = 0; + eight_bits *vpackets = xmalloc((unsigned) (10+10+1)); + if (e<0) { + half_w = -round_xn_over_d(quad(k), -e, 2000); + } else { + half_w = round_xn_over_d(quad(k), e, 2000); + } + co = get_charinfo(k, c); + w = char_width(k, c)+2*half_w; + set_charinfo_width(co, w); + append_packet(packet_right_code); + append_four(half_w); + append_fnt_set(f); + append_packet(packet_char_code); + append_four(c); + append_packet(packet_right_code); + append_four(half_w); + append_packet(packet_end_code); + set_charinfo_packets(co, vpackets); + } + } + /*tex Now patch the quad size. Ok, not in order to remain compatible with \PDFTEX: */ +#if 0 + if (e<0) { + set_font_param(k, quad_code, -round_xn_over_d(quad(k), 1000-e, 1000)); + } else { + set_font_param(k, quad_code, round_xn_over_d(quad(k), 1000+e, 1000)); + } +#endif + return k; +} + +internal_font_number copy_font_info(internal_font_number f) +{ + return copy_font(f); +} diff --git a/Build/source/texk/web2c/luatexdir/font/vfovf.w b/Build/source/texk/web2c/luatexdir/font/vfovf.w deleted file mode 100644 index df970ff4d11..00000000000 --- a/Build/source/texk/web2c/luatexdir/font/vfovf.w +++ /dev/null @@ -1,1480 +0,0 @@ -% vfovf.w -% -% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org> -% Copyright 2006-2013 Taco Hoekwater <taco@@luatex.org> -% -% This file is part of LuaTeX. -% -% LuaTeX 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. -% -% LuaTeX 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 Lesser General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License along -% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. - -@ @c - - -#include "ptexlib.h" - -@ @c -/* this is a hack! */ -#define font_max 5000 - -#define set_char_0 0 /* typeset character 0 and move right */ -#define set1 128 /* typeset a character and move right */ -#define set2 129 /* typeset a character and move right */ -#define set3 130 /* typeset a character and move right */ -#define set4 131 /* typeset a character and move right */ -#define set_rule 132 /* typeset a rule and move right */ -#define put1 133 /* typeset a character without moving */ -#define put2 134 /* typeset a character without moving */ -#define put3 135 /* typeset a character without moving */ -#define put4 136 /* typeset a character without moving */ -#define put_rule 137 /* typeset a rule */ -#define nop 138 /* no operation */ -#define bop 139 /* beginning of page */ -#define eop 140 /* ending of page */ -#define push 141 /* save the current positions */ -#define pop 142 /* restore previous positions */ -#define right1 143 /* move right */ -#define right2 144 /* move right */ -#define right3 145 /* move right */ -#define right4 146 /* move right, 4 bytes */ -#define w0 147 /* move right by |w| */ -#define w1 148 /* move right and set |w| */ -#define w2 149 /* move right and set |w| */ -#define w3 150 /* move right and set |w| */ -#define w4 151 /* move right and set |w| */ -#define x0 152 /* move right by |x| */ -#define x1 153 /* move right and set |x| */ -#define x2 154 /* move right and set |x| */ -#define x3 155 /* move right and set |x| */ -#define x4 156 /* move right and set |x| */ -#define down1 157 /* move down */ -#define down2 158 /* move down */ -#define down3 159 /* move down */ -#define down4 160 /* move down, 4 bytes */ -#define y0 161 /* move down by |y| */ -#define y1 162 /* move down and set |y| */ -#define y2 163 /* move down and set |y| */ -#define y3 164 /* move down and set |y| */ -#define y4 165 /* move down and set |y| */ -#define z0 166 /* move down by |z| */ -#define z1 167 /* move down and set |z| */ -#define z2 168 /* move down and set |z| */ -#define z3 169 /* move down and set |z| */ -#define z4 170 /* move down and set |z| */ -#define fnt_num_0 171 /* set current font to 0 */ -#define fnt1 235 /* set current font */ -#define fnt2 236 /* set current font */ -#define fnt3 237 /* set current font */ -#define fnt4 238 /* set current font */ -#define xxx1 239 /* extension to DVI primitives */ -#define xxx2 240 /* extension to DVI primitives */ -#define xxx3 241 /* extension to DVI primitives */ -#define xxx4 242 /* potentially long extension to DVI primitives */ -#define fnt_def1 243 /* define the meaning of a font number */ -#define pre 247 /* preamble */ -#define post 248 /* postamble beginning */ -#define post_post 249 /* postamble ending */ -#define yyy1 250 /* PDF literal text */ -#define yyy2 251 /* PDF literal text */ -#define yyy3 252 /* PDF literal text */ -#define yyy4 253 /* PDF literal text */ - -#define null_font 0 - -#define long_char 242 /* \.{VF} command for general character packet */ -#define vf_id 202 /* identifies \.{VF} files */ - -@ go out \.{VF} processing with an error message -@c -#define bad_vf(a) { \ - xfree(vf_buffer); \ - print_nlp(); \ - formatted_warning("virtual font","file '%s', %s, font will be ignored",font_name(f),a); \ - print_ln(); \ - return; \ -} - -#define lua_bad_vf(a) { \ - xfree(vf_buffer); \ - lua_settop(L,s_top); \ - lua_pushnil(L); \ - lua_pushstring(L,a); \ - return 2; \ -} - -#define tmp_b0 tmp_w.qqqq.b0 -#define tmp_b1 tmp_w.qqqq.b1 -#define tmp_b2 tmp_w.qqqq.b2 -#define tmp_b3 tmp_w.qqqq.b3 -#define tmp_int tmp_w.cint - -#define vf_stack_size 100 /* \.{DVI} files shouldn't |push| beyond this depth */ - -@ @c -typedef unsigned char vf_stack_index; /* an index into the stack */ - -typedef struct vf_stack_record { - scaled stack_w, stack_x, stack_y, stack_z; -} vf_stack_record; - -@ get a byte from\.{VF} file -@c -#define vf_byte(a) \ -{ \ - eight_bits vf_tmp_b; \ - if (vf_cur >= vf_size) { \ - normal_error("virtual font","unexpected eof"); \ - } \ - vf_tmp_b = vf_buffer[vf_cur++]; \ - a = vf_tmp_b; \ -} - -@ @c -#define vf_replace_z() \ -{ \ - vf_alpha = 16; \ - while (vf_z >= 040000000) { \ - vf_z = vf_z / 2; \ - vf_alpha += vf_alpha; \ - } \ - /*vf_beta = (char)(256 / vf_alpha);*/ \ - vf_alpha = (vf_alpha * vf_z); \ -} - - -@ read |k| bytes as an integer from \.{VF} file -beware: the |vf_read()| macro differs from |vf_read()| in vftovp.web for 1...3 byte words. -@c -#define vf_read(k, l) \ -{ \ - int itmp = 0, dtmp = (int)(k), jtmp = 0; \ - while (dtmp > 0) { \ - vf_byte(jtmp); \ - if ((dtmp == (int) k) && jtmp > 127) \ - jtmp = jtmp - 256; \ - itmp = itmp * 256 + jtmp; \ - decr(dtmp); \ - } \ - l = itmp; \ -} - -#define vf_read_u(k, l) \ -{ \ - int dtmp = (int)(k); \ - unsigned int itmp = 0, jtmp = 0; \ - while (dtmp-- > 0) { \ - vf_byte(jtmp); \ - itmp = itmp * 256 + jtmp; \ - } \ - l = itmp; \ -} - -@ @c -void pdf_check_vf(internal_font_number f) -{ - if (font_type(f) == virtual_font_type) - normal_error("font", "command cannot be used with virtual font"); -} - -static void -vf_local_font_warning(internal_font_number f, internal_font_number k, const char *s, int a, int b) -{ - print_nlp(); - tprint(s); - tprint(" in local font "); - tprint(font_name(k)); - tprint(" ("); - print_int(b); - tprint(" != "); - print_int(a); - tprint(") in virtual font "); - tprint(font_name(f)); - tprint(".vf ignored."); -} - - -@ process a local font in \.{VF} file -@c -int level = 0; - -static internal_font_number -vf_def_font(internal_font_number f, unsigned char *vf_buffer, int *vf_cr) -{ - internal_font_number k; - str_number s; - char *st; - scaled ds, fs; - four_quarters cs; - memory_word tmp_w; /* accumulator */ - int junk; - unsigned int checksum; - cs.b0 = vf_buffer[(*vf_cr)]; - cs.b1 = vf_buffer[(*vf_cr) + 1]; - cs.b2 = vf_buffer[(*vf_cr) + 2]; - cs.b3 = vf_buffer[(*vf_cr) + 3]; - (*vf_cr) += 4; - checksum = (unsigned) - (cs.b0 * 256 * 256 * 256 + cs.b1 * 256 * 256 + cs.b2 * 256 + cs.b3); - k = vf_buffer[(*vf_cr)]; - (*vf_cr)++; - if (k > 127) - k -= 256; - k = k * 256 + vf_buffer[(*vf_cr)]; - (*vf_cr)++; - k = k * 256 + vf_buffer[(*vf_cr)]; - (*vf_cr)++; - k = k * 256 + vf_buffer[(*vf_cr)]; - (*vf_cr)++; - - fs = store_scaled_f(k, font_size(f)); - - k = vf_buffer[(*vf_cr)]; - (*vf_cr)++; - if (k > 127) - k -= 256; - k = k * 256 + vf_buffer[(*vf_cr)]; - (*vf_cr)++; - k = k * 256 + vf_buffer[(*vf_cr)]; - (*vf_cr)++; - k = k * 256 + vf_buffer[(*vf_cr)]; - (*vf_cr)++; - - ds = k / 16; - - - tmp_b0 = vf_buffer[(*vf_cr)]; - (*vf_cr)++; - tmp_b1 = vf_buffer[(*vf_cr)]; - (*vf_cr)++; - while (tmp_b0 > 0) { - tmp_b0--; - (*vf_cr)++; /* skip the font path */ - } - str_room((unsigned) tmp_b1); - while (tmp_b1 > 0) { - tmp_b1--; - junk = vf_buffer[(*vf_cr)]; - (*vf_cr)++; - append_char(junk); - } - if (level > 5) { - normal_warning("vf","quitting at recurse depth > 5"); - k = f ; - } else if ((level > 1) && (fs > 65536*1024)) { - normal_warning("vf","quitting when recursing at size > 65536*1024"); - k = f ; - } else { - level += 1 ; - s = make_string(); - st = makecstring(s); - k = tfm_lookup(st, fs); - if (k == null_font) - k = read_font_info(null_cs, st, fs, -1); - free(st); - level -= 1 ; - if (k != null_font) { - if (checksum != 0 && font_checksum(k) != 0 - && checksum != font_checksum(k)) - vf_local_font_warning(f, k, "checksum mismatch", (int) checksum, (int) font_checksum(k)); - if (ds != font_dsize(k)) - vf_local_font_warning(f, k, "design size mismatch", ds, font_dsize(k)); - } - } - return k; -} - -@ @c -static int open_vf_file(const char *fn, unsigned char **vbuffer, int *vsize) -{ - boolean res; /* was the callback successful? */ - int callback_id; - boolean file_read = false; /* was |vf_file| successfully read? */ - FILE *vf_file; - const char *fname = luatex_find_file(fn, find_vf_file_callback); - if (fname == NULL || strlen(fname) == 0) { - /* fname = fn; */ - return 0; - } - - callback_id = callback_defined(read_vf_file_callback); - if (callback_id > 0) { - res = run_callback(callback_id, "S->bSd", fname, - &file_read, vbuffer, vsize); - if (res && file_read && (*vsize > 0)) { - return 1; - } - if (!file_read) - return 0; /* -1 */ - } else { - if (luatex_open_input - (&(vf_file), fname, kpse_ovf_format, FOPEN_RBIN_MODE, false) - || luatex_open_input(&(vf_file), fname, kpse_vf_format, - FOPEN_RBIN_MODE, false)) { - res = read_vf_file(vf_file, vbuffer, vsize); - close_file(vf_file); - if (res) { - return 1; - } - } else { - return 0; /* -1 */ - } - } - return 0; -} - - - -@ The |do_vf| procedure attempts to read the \.{VF} file for a font, and sets - |font_type()| to |real_font_type| if the \.{VF} file could not be found - or loaded, otherwise sets |font_type()| to |virtual_font_type|. At this - time, |tmp_f| is the internal font number of the current \.{TFM} font. To - process font definitions in virtual font we call |vf_def_font|. - -@c -#define append_packet(k) vpackets[vf_np++] = (eight_bits)(k) - -@ life is easier if all internal font commands are fnt4 and - all character commands are set4 or put4 - -@c -#define append_fnt_set(k) \ -{ \ - assert(k > 0); \ - append_packet(packet_font_code); \ - append_four(k); \ -} - -#define append_four(k) \ -{ \ - append_packet((k & 0xFF000000) >> 24); \ - append_packet((k & 0x00FF0000) >> 16); \ - append_packet((k & 0x0000FF00) >> 8); \ - append_packet((k & 0x000000FF)); \ -} - -@ some of these things happen twice, adding a define is simplest - -@c -#define test_checksum() { vf_byte(tmp_b0); vf_byte(tmp_b1); \ - vf_byte(tmp_b2); vf_byte(tmp_b3); \ - if (((tmp_b0 != 0) || (tmp_b1 != 0) || (tmp_b2 != 0) || (tmp_b3 != 0)) && \ - ((font_check_0(f) != 0) || (font_check_1(f) != 0) || \ - (font_check_2(f) != 0) || (font_check_3(f) != 0)) && \ - ((tmp_b0 != font_check_0(f)) || (tmp_b1 != font_check_1(f)) || \ - (tmp_b2 != font_check_2(f)) || (tmp_b3 != font_check_3(f)))) { \ - print_nlp(); \ - tprint("checksum mismatch in font "); \ - tprint(font_name(f)); \ - tprint(".vf ignored "); } } - -#define test_dsize() \ -{ \ - int read_tmp; \ - vf_read(4, read_tmp); \ - if ((read_tmp / 16) != font_dsize(f)) { \ - print_nlp(); \ - tprint("design size mismatch in font "); \ - tprint(font_name(f)); \ - tprint(".vf ignored"); \ - } \ -} - -@ @c -static int count_packet_bytes(eight_bits * vf_buf, int cur_bute, int count) -{ - unsigned k = 0; - int ff = 0; - int acc = 0; - unsigned int cmd = 0; - unsigned int d = 0; - while (k < (unsigned) count) { - cmd = vf_buf[cur_bute + (int) k]; - k++; - if (cmd < set1) { - if (ff == 0) { - ff = 1; - acc += 5; - } - acc += 5; - } else if ((fnt_num_0 <= cmd) && (cmd <= fnt_num_0 + 63)) { - ff = 1; - acc += 5; - } else { - switch (cmd) { - case fnt1: - acc += 5; - k += 1; - ff = 1; - break; - case fnt2: - acc += 5; - k += 2; - ff = 1; - break; - case fnt3: - acc += 5; - k += 3; - ff = 1; - break; - case fnt4: - acc += 5; - k += 4; - ff = 1; - break; - case set_rule: - acc += 9; - k += 8; - break; - case put_rule: - acc += 11; - k += 8; - break; - case set1: - acc += 5; - k += 1; - if (ff == 0) { - ff = 1; - acc += 5; - } - break; - case set2: - acc += 5; - k += 2; - if (ff == 0) { - ff = 1; - acc += 5; - } - break; - case set3: - acc += 5; - k += 3; - if (ff == 0) { - ff = 1; - acc += 5; - } - break; - case set4: - acc += 5; - k += 4; - if (ff == 0) { - ff = 1; - acc += 5; - } - break; - case put1: - acc += 7; - k += 1; - if (ff == 0) { - ff = 1; - acc += 5; - } - break; - case put2: - acc += 7; - k += 2; - if (ff == 0) { - ff = 1; - acc += 5; - } - break; - case put3: - acc += 7; - k += 3; - if (ff == 0) { - ff = 1; - acc += 5; - } - break; - case put4: - acc += 7; - k += 4; - if (ff == 0) { - ff = 1; - acc += 5; - } - break; - case right1: - acc += 5; - k += 1; - break; - case right2: - acc += 5; - k += 2; - break; - case right3: - acc += 5; - k += 3; - break; - case right4: - acc += 5; - k += 4; - break; - case w1: - acc += 5; - k += 1; - break; - case w2: - acc += 5; - k += 2; - break; - case w3: - acc += 5; - k += 3; - break; - case w4: - acc += 5; - k += 4; - break; - case x1: - acc += 5; - k += 1; - break; - case x2: - acc += 5; - k += 2; - break; - case x3: - acc += 5; - k += 3; - break; - case x4: - acc += 5; - k += 4; - break; - case down1: - acc += 5; - k += 1; - break; - case down2: - acc += 5; - k += 2; - break; - case down3: - acc += 5; - k += 3; - break; - case down4: - acc += 5; - k += 4; - break; - case y1: - acc += 5; - k += 1; - break; - case y2: - acc += 5; - k += 2; - break; - case y3: - acc += 5; - k += 3; - break; - case y4: - acc += 5; - k += 4; - break; - case z1: - acc += 5; - k += 1; - break; - case z2: - acc += 5; - k += 2; - break; - case z3: - acc += 5; - k += 3; - break; - case z4: - acc += 5; - k += 4; - break; - case xxx1: - d = vf_buf[cur_bute + (int) k]; - k++; - k += d; - acc += 5 + (int) d; - break; - case xxx2: - d = vf_buf[cur_bute + (int) k]; - k++; - d = d * 256 + vf_buf[cur_bute + (int) k]; - k++; - k += d; - acc += 5 + (int) d; - break; - case xxx3: - d = vf_buf[cur_bute + (int) k]; - k++; - d = d * 256 + vf_buf[cur_bute + (int) k]; - k++; - d = d * 256 + vf_buf[cur_bute + (int) k]; - k++; - k += d; - acc += 5 + (int) d; - break; - case xxx4: - d = vf_buf[cur_bute + (int) k]; - k++; - d = d * 256 + vf_buf[cur_bute + (int) k]; - k++; - d = d * 256 + vf_buf[cur_bute + (int) k]; - k++; - d = d * 256 + vf_buf[cur_bute + (int) k]; - k++; - k += d; - acc += 5 + (int) d; - break; - case w0: - acc += 5; - break; - case x0: - acc += 5; - break; - case y0: - acc += 5; - break; - case z0: - acc += 5; - break; - case nop: - break; - case push: - acc += 1; - break; - case pop: - acc += 1; - break; - } - } - } - return (acc + 1); -} - -@ @c -void do_vf(internal_font_number f) -{ - int k, i; - unsigned cmd, n; - scaled x, y, w, z, h, v; - int cc, cmd_length; - unsigned packet_length; - charinfo *co; - scaled tfm_width; - int save_cur_byte; - vf_stack_index stack_level; - int vf_z; /* multiplier */ - int vf_alpha; /* correction for negative values */ - /*char vf_beta;*/ /* divisor */ - int vf_np; - eight_bits *vpackets; - memory_word tmp_w; /* accumulator */ - vf_stack_record vf_stack[256]; - int junk; - unsigned utmp; - unsigned char *vf_buffer; - int vf_size; - int vf_cur; - unsigned *vf_local_fnts = NULL; /* external font ids */ - unsigned *vf_real_fnts = NULL; /* internal font ids */ - unsigned vf_nf = 0; /* local font counter */ - - if (font_type(f) != unknown_font_type) - return; - set_font_type(f, real_font_type); - stack_level = 0; - /* Open |vf_file|, return if not found */ - vf_cur = 0; - vf_buffer = NULL; - vf_size = 0; - if (!open_vf_file(font_name(f), &vf_buffer, &vf_size)) - return; - /* Process the preamble */ - set_font_type(f, virtual_font_type); - vf_byte(k); - if (k != pre) - bad_vf("PRE command expected"); - vf_byte(k); - if (k != vf_id) - bad_vf("wrong id byte"); - vf_byte(cmd_length); - for (k = 1; k <= cmd_length; k++) - vf_byte(junk); - test_checksum(); - test_dsize(); - vf_z = font_size(f); - vf_replace_z(); - /* Process the font definitions */ - /* scan forward to find the number of internal fonts */ - vf_nf = 0; - save_cur_byte = vf_cur; - vf_byte(cmd); - while ((cmd >= fnt_def1) && (cmd <= (fnt_def1 + 3))) { - vf_read_u((cmd - fnt_def1 + 1), utmp); - vf_read(4, junk); - vf_read(4, junk); - vf_read(4, junk); - vf_byte(k); - vf_byte(junk); - k += junk; - while (k-- > 0) { - vf_byte(junk); - } - incr(vf_nf); - vf_byte(cmd); - } - vf_cur = save_cur_byte; - vf_byte(cmd); - /* malloc and fill the local font arrays */ - if (vf_nf > 0) { - unsigned ii = (unsigned) ((unsigned) vf_nf * sizeof(int)); - vf_local_fnts = xmalloc(ii); - memset(vf_local_fnts, 0, ii); - vf_real_fnts = xmalloc(ii); - memset(vf_real_fnts, 0, ii); - vf_nf = 0; - while ((cmd >= fnt_def1) && (cmd <= (fnt_def1 + 3))) { - vf_read_u((cmd - fnt_def1 + 1), vf_local_fnts[vf_nf]); - vf_real_fnts[vf_nf] = (unsigned) vf_def_font(f, vf_buffer, &vf_cur); - incr(vf_nf); - vf_byte(cmd); - } - } - - - while (cmd <= long_char) { - /* Build a character packet */ - vf_np = 0; - if (cmd == long_char) { - vf_read_u(4, packet_length); - vf_read_u(4, utmp); - cc = (int) utmp; - if (!char_exists(f, cc)) { - bad_vf("invalid character code"); - } - vf_read(4, k); - tfm_width = store_scaled_f(k, font_size(f)); - } else { - packet_length = cmd; - vf_byte(cc); - if (!char_exists(f, cc)) { - bad_vf("invalid character code"); - } - vf_read_u(3, utmp); - k = (int) utmp; /* cf. vftovp.web, line 1028 */ - tfm_width = store_scaled_f(k, font_size(f)); - } - - - if (tfm_width != char_width(f, cc)) { - if (tfm_width != char_width(f, cc)) { - print_nlp(); - tprint("character width mismatch in font "); - tprint(font_name(f)); - tprint(".vf ignored"); - } - } - k = count_packet_bytes(vf_buffer, vf_cur, (int) packet_length); - vpackets = xmalloc((unsigned) (k + 1)); /* need one extra extra for |packet_end| */ - co = get_charinfo(f, cc); - k = 0; - w = 0; - x = 0; - y = 0; - z = 0; - while (packet_length > 0) { - vf_byte(cmd); - decr(packet_length); - - if (cmd < set1) { - if (k == 0) { - k = (int) vf_real_fnts[0]; - append_fnt_set(k); - } - append_packet(packet_char_code); - append_four(cmd); - cmd_length = 0; - cmd = nop; - - } else if (((fnt_num_0 <= cmd) && (cmd <= fnt_num_0 + 63)) || - ((fnt1 <= cmd) && (cmd <= fnt1 + 3))) { - if (cmd >= fnt1) { - vf_read_u((cmd - fnt1 + 1), utmp); - k = (int) utmp; - packet_length -= (cmd - fnt1 + 1); - } else { - k = (int) cmd - fnt_num_0; - } - - /* change from local to external font id */ - n = 0; - while ((n < vf_nf) && (vf_local_fnts[n] != (unsigned) k)) - n++; - if (n == vf_nf) - bad_vf("undefined local font"); - - k = (int) vf_real_fnts[n]; - append_fnt_set(k); - cmd_length = 0; - cmd = nop; - } else { - switch (cmd) { - case set_rule: - vf_read(4, h); - vf_read(4, v); - append_packet(packet_rule_code); - append_four(h); - append_four(v); - packet_length -= 8; - break; - case put_rule: - vf_read(4, h); - vf_read(4, v); - append_packet(packet_push_code); - append_packet(packet_rule_code); - append_four(h); - append_four(v); - append_packet(packet_pop_code); - packet_length -= 8; - break; - case set1: - case set2: - case set3: - case set4: - if (k == 0) { - k = (int) vf_real_fnts[0]; - append_fnt_set(k); - } - vf_read_u((cmd - set1 + 1), utmp); - i = (int) utmp; - append_packet(packet_char_code); - append_four(i); - packet_length -= (cmd - set1 + 1); - break; - case put1: - case put2: - case put3: - case put4: - if (k == 0) { - k = (int) vf_real_fnts[0]; - append_fnt_set(k); - } - vf_read_u((cmd - put1 + 1), utmp); - i = (int) utmp; - append_packet(packet_push_code); - append_packet(packet_char_code); - append_four(i); - append_packet(packet_pop_code); - packet_length -= (cmd - put1 + 1); - break; - case right1: - case right2: - case right3: - case right4: - vf_read((cmd - right1 + 1), i); - append_packet(packet_right_code); - append_four(i); - packet_length -= (cmd - right1 + 1); - break; - case w1: - case w2: - case w3: - case w4: - vf_read((cmd - w1 + 1), w); - append_packet(packet_right_code); - append_four(w); - packet_length -= (cmd - w1 + 1); - break; - case x1: - case x2: - case x3: - case x4: - vf_read((cmd - x1 + 1), x); - append_packet(packet_right_code); - append_four(x); - packet_length -= (cmd - x1 + 1); - break; - case down1: - case down2: - case down3: - case down4: - vf_read((cmd - down1 + 1), i); - append_packet(packet_down_code); - append_four(i); - packet_length -= (cmd - down1 + 1); - break; - case y1: - case y2: - case y3: - case y4: - vf_read((cmd - y1 + 1), y); - append_packet(packet_down_code); - append_four(y); - packet_length -= (cmd - y1 + 1); - break; - case z1: - case z2: - case z3: - case z4: - vf_read((cmd - z1 + 1), z); - append_packet(packet_down_code); - append_four(z); - packet_length -= (cmd - z1 + 1); - break; - case xxx1: - case xxx2: - case xxx3: - case xxx4: - vf_read_u((cmd - xxx1 + 1), utmp); - cmd_length = (int) utmp; - packet_length -= (cmd - xxx1 + 1); - if (cmd_length <= 0) - bad_vf("special of negative length"); - packet_length -= (unsigned) cmd_length; - - append_packet(packet_special_code); - append_four(cmd_length); - while (cmd_length > 0) { - cmd_length--; - vf_byte(i); - append_packet(i); - } - break; - case w0: - append_packet(packet_right_code); - append_four(w); - break; - case x0: - append_packet(packet_right_code); - append_four(x); - break; - case y0: - append_packet(packet_down_code); - append_four(y); - break; - case z0: - append_packet(packet_down_code); - append_four(z); - break; - case nop: - break; - case push: - if (stack_level == vf_stack_size) { - overflow("virtual font stack size", vf_stack_size); - } else { - vf_stack[stack_level].stack_w = w; - vf_stack[stack_level].stack_x = x; - vf_stack[stack_level].stack_y = y; - vf_stack[stack_level].stack_z = z; - incr(stack_level); - append_packet(packet_push_code); - } - break; - case pop: - if (stack_level == 0) { - bad_vf("more POPs than PUSHs in character"); - } else { - decr(stack_level); - w = vf_stack[stack_level].stack_w; - x = vf_stack[stack_level].stack_x; - y = vf_stack[stack_level].stack_y; - z = vf_stack[stack_level].stack_z; - append_packet(packet_pop_code); - } - break; - default: - bad_vf("improver DVI command"); - } - } - } - /* signal end of packet */ - append_packet(packet_end_code); - - if (stack_level != 0) - bad_vf("more PUSHs than POPs in character packet"); - if (packet_length != 0) - bad_vf("invalid packet length or DVI command in packet"); - /* \.{Store the packet being built} */ - set_charinfo_packets(co, vpackets); - vf_byte(cmd); - } - if (cmd != post) - bad_vf("POST command expected"); - - xfree(vf_buffer); -} - -@ @c -#define make_command0(N,K) { \ - lua_newtable(L); \ - lua_pushstring(L, N); \ - lua_rawseti(L,-2, 1); \ - lua_rawseti(L,-2, K); \ - K++; } - -#define make_command1(N,V,K) { \ - lua_newtable(L); \ - lua_pushstring(L, N); \ - lua_rawseti(L,-2, 1); \ - lua_pushinteger(L, V); \ - lua_rawseti(L,-2, 2); \ - lua_rawseti(L,-2, K); \ - K++; } - -#define make_command2(N,V,W,K) { \ - lua_newtable(L); \ - lua_pushstring(L, N); \ - lua_rawseti(L,-2, 1); \ - lua_pushinteger(L, V); \ - lua_rawseti(L,-2, 2); \ - lua_pushinteger(L, W); \ - lua_rawseti(L,-2, 3); \ - lua_rawseti(L,-2, K); \ - K++; } - -#define make_commands(N,S,V,K) { \ - lua_newtable(L); \ - lua_pushstring(L, N); \ - lua_rawseti(L,-2, 1); \ - lua_pushlstring(L, S, V); \ - lua_rawseti(L,-2, 2); \ - lua_rawseti(L,-2, K); \ - K++; } - - -int make_vf_table(lua_State * L, const char *cnom, scaled atsize) -{ - int cmd, k, i; - int cc; - unsigned cmd_length, packet_length; - scaled tfm_width; - vf_stack_index stack_level; - int vf_z; /* multiplier */ - int vf_alpha; /* correction for negative values */ - /*char vf_beta;*/ /* divisor */ - eight_bits *s; - scaled h, v; - scaled w, x, y, z; - int s_top; /* lua stack */ - int vf_nf; /* local font counter */ - scaled ds, fs; - four_quarters cs; - memory_word tmp_w; /* accumulator */ - vf_stack_record vf_stack[256]; - unsigned char *vf_buffer; - int vf_size; - int vf_cur; - unsigned utmp; - - - stack_level = 0; - /* Open |vf_file|, return if not found */ - vf_cur = 0; - vf_buffer = NULL; - vf_size = 0; - if (!open_vf_file(cnom, &vf_buffer, &vf_size)) { - lua_pushnil(L); - return 1; - } - - /* start by creating a table */ - s_top = lua_gettop(L); - lua_newtable(L); - - /* Process the preamble */ - vf_byte(k); - if (k != pre) - lua_bad_vf("PRE command expected"); - vf_byte(k); - if (k != vf_id) - lua_bad_vf("wrong id byte"); - vf_byte(cmd_length); - - s = xmalloc(cmd_length); - for (k = 1; k <= (int) cmd_length; k++) - vf_byte(s[(k - 1)]); - - lua_pushlstring(L, (char *) s, (size_t) cmd_length); - free(s); - lua_setfield(L, -2, "header"); - - vf_byte(cs.b0); - vf_byte(cs.b1); - vf_byte(cs.b2); - vf_byte(cs.b3); - lua_pushinteger(L, (lua_Number) ((cs.b0 << 24) + (cs.b1 << 16) + (cs.b2 << 8) + cs.b3)); - lua_setfield(L, -2, "checksum"); - - vf_read(4, k); - ds = k / 16; - lua_pushinteger(L, ds); - lua_setfield(L, -2, "designsize"); - - - lua_pushstring(L, cnom); - lua_setfield(L, -2, "name"); - - lua_pushinteger(L, atsize); - lua_setfield(L, -2, "size"); - - vf_z = atsize; - vf_replace_z(); - /* Process the font definitions */ - vf_byte(cmd); - lua_newtable(L); - - i = 1; - while ((cmd >= fnt_def1) && (cmd <= fnt_def1 + 3)) { - - lua_newtable(L); - vf_read_u((cmd - fnt_def1 + 1), utmp); - vf_nf = (int) utmp; - vf_nf++; - /* checksum */ - vf_byte(cs.b0); - vf_byte(cs.b1); - vf_byte(cs.b2); - vf_byte(cs.b3); - - vf_read(4, k); - fs = store_scaled_f(k, atsize); - lua_pushstring(L, "size"); - lua_pushinteger(L, fs); - lua_rawset(L, -3); - - vf_read(4, k); - ds = k / 16; /* dsize, not used */ - - vf_byte(tmp_b0); - vf_byte(tmp_b1); - while (tmp_b0 > 0) { - tmp_b0--; - vf_byte(k); - } /* skip the font path */ - - s = xmalloc((unsigned) (tmp_b1 + 1)); - k = 0; - while (tmp_b1-- > 0) - vf_byte(s[k++]); - s[k] = 0; - lua_pushstring(L, "name"); - lua_pushstring(L, xstrdup((char *) s)); - free(s); - lua_rawset(L, -3); - - lua_rawseti(L, -2, vf_nf); - i++; - vf_byte(cmd); - } - - if (i > 1) { - lua_setfield(L, -2, "fonts"); - } else { - lua_pop(L, 1); - } - - lua_newtable(L); /* 'characters' */ - while (cmd <= long_char) { - /* Build a character packet */ - if (cmd == long_char) { - vf_read_u(4, packet_length); - vf_read_u(4, utmp); - cc = (int) utmp; - vf_read(4, tfm_width); - } else { - packet_length = (unsigned) cmd; - vf_byte(cc); - vf_read_u(3, utmp); - tfm_width = (int) utmp; - } - lua_newtable(L); /* for this character */ - lua_pushinteger(L, tfm_width); - lua_setfield(L, -2, "width"); - lua_newtable(L); /* for 'commands' */ - k = 1; - vf_nf = 0; - w = 0; - x = 0; - y = 0; - z = 0; - while (packet_length > 0) { - vf_byte(cmd); - decr(packet_length); - if ((cmd >= set_char_0) && (cmd < set1)) { - if (vf_nf == 0) { - vf_nf = 1; - make_command1("font", vf_nf, k); - } - make_command1("char", cmd, k); - } else if (((fnt_num_0 <= cmd) && (cmd <= fnt_num_0 + 63)) || - ((fnt1 <= cmd) && (cmd <= fnt1 + 3))) { - if (cmd >= fnt1) { - vf_read_u((cmd - fnt1 + 1), utmp); - vf_nf = (int) utmp; - vf_nf++; - packet_length -= (unsigned) (cmd - fnt1 + 1); - } else { - vf_nf = cmd - fnt_num_0 + 1; - } - make_command1("font", vf_nf, k); - } else { - switch (cmd) { - case set_rule: - vf_read(4, h); - vf_read(4, v); - make_command2("rule", store_scaled_f(h, atsize), - store_scaled_f(v, atsize), k); - packet_length -= 8; - break; - case put_rule: - vf_read(4, h); - vf_read(4, v); - make_command0("push", k); - make_command2("rule", store_scaled_f(h, atsize), - store_scaled_f(v, atsize), k); - make_command0("pop", k); - packet_length -= 8; - break; - case set1: - case set2: - case set3: - case set4: - if (vf_nf == 0) { - vf_nf = 1; - make_command1("font", vf_nf, k); - } - vf_read_u((cmd - set1 + 1), utmp); - i = (int) utmp; - make_command1("char", i, k); - packet_length -= (unsigned) (cmd - set1 + 1); - break; - case put1: - case put2: - case put3: - case put4: - if (vf_nf == 0) { - vf_nf = 1; - make_command1("font", vf_nf, k); - } - vf_read_u((cmd - put1 + 1), utmp); - i = (int) utmp; - make_command0("push", k); - make_command1("char", i, k); - make_command0("pop", k); - packet_length -= (unsigned) (cmd - put1 + 1); - break; - case right1: - case right2: - case right3: - case right4: - vf_read((cmd - right1 + 1), i); - make_command1("right", store_scaled_f(i, atsize), k); - packet_length -= (unsigned) (cmd - right1 + 1); - break; - case w1: - case w2: - case w3: - case w4: - vf_read((cmd - w1 + 1), w); - make_command1("right", store_scaled_f(w, atsize), k); - packet_length -= (unsigned) (cmd - w1 + 1); - break; - case x1: - case x2: - case x3: - case x4: - vf_read((cmd - x1 + 1), x); - make_command1("right", store_scaled_f(x, atsize), k); - packet_length -= (unsigned) (cmd - x1 + 1); - break; - case down1: - case down2: - case down3: - case down4: - vf_read((cmd - down1 + 1), i); - make_command1("down", store_scaled_f(i, atsize), k); - packet_length -= (unsigned) (cmd - down1 + 1); - break; - case y1: - case y2: - case y3: - case y4: - vf_read((cmd - y1 + 1), y); - make_command1("down", store_scaled_f(y, atsize), k); - packet_length -= (unsigned) (cmd - y1 + 1); - break; - case z1: - case z2: - case z3: - case z4: - vf_read((cmd - z1 + 1), z); - make_command1("down", store_scaled_f(z, atsize), k); - packet_length -= (unsigned) (cmd - z1 + 1); - break; - case xxx1: - case xxx2: - case xxx3: - case xxx4: - vf_read_u((cmd - xxx1 + 1), cmd_length); - packet_length -= (unsigned) (cmd - xxx1 + 1); - if (cmd_length <= 0) - lua_bad_vf("special of negative length"); - packet_length -= cmd_length; - - s = xmalloc((cmd_length + 1)); - i = 0; - while (cmd_length > 0) { - cmd_length--; - vf_byte(s[i]); - i++; - } - s[i] = 0; - make_commands("special", xstrdup((char *) s), (size_t) i, - k); - free(s); - break; - case w0: - make_command1("right", store_scaled_f(w, atsize), k); - break; - case x0: - make_command1("right", store_scaled_f(x, atsize), k); - break; - case y0: - make_command1("down", store_scaled_f(y, atsize), k); - break; - case z0: - make_command1("down", store_scaled_f(z, atsize), k); - break; - case nop: - break; - case push: - if (stack_level == vf_stack_size) { - overflow("virtual font stack size", vf_stack_size); - } else { - vf_stack[stack_level].stack_w = w; - vf_stack[stack_level].stack_x = x; - vf_stack[stack_level].stack_y = y; - vf_stack[stack_level].stack_z = z; - incr(stack_level); - make_command0("push", k); - } - break; - case pop: - if (stack_level == 0) { - lua_bad_vf("more POPs than PUSHs in character"); - } else { - decr(stack_level); - w = vf_stack[stack_level].stack_w; - x = vf_stack[stack_level].stack_x; - y = vf_stack[stack_level].stack_y; - z = vf_stack[stack_level].stack_z; - make_command0("pop", k); - } - break; - default: - lua_bad_vf("improver DVI command"); - } - } - } - /* signal end of packet */ - lua_setfield(L, -2, "commands"); - - if (stack_level != 0) - lua_bad_vf("more PUSHs than POPs in character packet"); - if (packet_length != 0) - lua_bad_vf("invalid packet length or DVI command in packet"); - - lua_rawseti(L, -2, cc); - - vf_byte(cmd); - } - lua_setfield(L, -2, "characters"); - - if (cmd != post) - lua_bad_vf("POST command expected"); - xfree(vf_buffer); - return 1; -} - -@ @c -internal_font_number -letter_space_font(internal_font_number f, int e, boolean nolig) -{ - internal_font_number k; - scaled w; - int c; - charinfo *co; - char *new_font_name; - - /* read a new font and expand the character widths */ - k = copy_font(f); - - if (nolig) - set_no_ligatures(k); /* disable ligatures for letter-spaced fonts */ - - /* append eg '+100ls' to font name */ - new_font_name = xmalloc((unsigned) (strlen(font_name(k)) + 8)); /* |abs(e) <= 1000| */ - if (e > 0) { - sprintf(new_font_name, "%s+%ils", font_name(k), (int) e); - } else { - /* minus from \%i */ - sprintf(new_font_name, "%s%ils", font_name(k), (int) e); - } - set_font_name(k, new_font_name); - - /* create the corresponding virtual font */ - set_font_type(k, virtual_font_type); - - for (c=font_bc(k);c<=font_ec(k);c++) { - if (quick_char_exists(k, c)) { - int half_w; - int vf_np = 0; - eight_bits *vpackets = xmalloc((unsigned) (10+10+1)); - if (e<0) { - half_w = -round_xn_over_d(quad(k), -e, 2000); - } else { - half_w = round_xn_over_d(quad(k), e, 2000); - } - co = get_charinfo(k, c); - w = char_width(k, c)+2*half_w; - set_charinfo_width(co, w); - - append_packet(packet_right_code); - append_four(half_w); - append_fnt_set(f); - append_packet(packet_char_code); - append_four(c); - append_packet(packet_right_code); - append_four(half_w); - append_packet(packet_end_code); - - set_charinfo_packets(co, vpackets); - } - } - /* now patch the quad size */ - /* Patch 20100922: do not do this, to remain compatible with pdftex */ -#if 0 - if (e<0) { - set_font_param(k, quad_code, -round_xn_over_d(quad(k), 1000-e, 1000)); - } else { - set_font_param(k, quad_code, round_xn_over_d(quad(k), 1000+e, 1000)); - } -#endif - return k; -} - -@ @c -internal_font_number copy_font_info(internal_font_number f) -{ - return copy_font(f); -} diff --git a/Build/source/texk/web2c/luatexdir/font/vfpacket.c b/Build/source/texk/web2c/luatexdir/font/vfpacket.c new file mode 100644 index 00000000000..41132c54a6d --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/font/vfpacket.c @@ -0,0 +1,445 @@ +/* + +Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> +Copyright 2006-2013 Taco Hoekwater <taco@luatex.org> + +This file is part of LuaTeX. + +LuaTeX 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. + +LuaTeX 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU General Public License along +with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +*/ + +#include "ptexlib.h" +#include "lua/luatex-api.h" + +/*tex + + Some macros for processing character packets. + +*/ + +#define packet_number(fw) { \ + fw = *(vfp++); \ + fw = fw * 256 + *(vfp++); \ + fw = fw * 256 + *(vfp++); \ + fw = fw * 256 + *(vfp++); \ +} + +#define packet_scaled(a, fs) { \ + int fw; \ + fw = *(vfp++); \ + if (fw > 127) \ + fw = fw - 256; \ + fw = fw * 256 + *(vfp++); \ + fw = fw * 256 + *(vfp++); \ + fw = fw * 256 + *(vfp++); \ + a = store_scaled_f(fw, fs); \ +} + +vf_struct *new_vfstruct(void) +{ + vf_struct *vp = (vf_struct *) xmalloc(sizeof(vf_struct)); + vp->packet_stack_level = vp->packet_stack_minlevel = 0; + vp->packet_stack = (packet_stack_record *) xmalloc(packet_stack_size * sizeof(packet_stack_record)); + vp->lf = 0; + vp->fs_f = 0; + vp->packet_cur_s = 0; + vp->refpos = NULL; + vp->vflua = false; + return vp; +} + +/*tex + + Count the number of bytes in a command packet. +*/ + +int vf_packet_bytes(charinfo * co) +{ + eight_bits *vf_packets, *vfp; + unsigned k; + int cmd; + vfp = vf_packets = get_charinfo_packets(co); + if (vf_packets == NULL) { + return 0; + } + while ((cmd = *(vfp++)) != packet_end_code) { + switch (cmd) { + case packet_nop_code: + case packet_pop_code: + case packet_push_code: + break; + case packet_char_code: + case packet_down_code: + case packet_font_code: + case packet_image_code: + case packet_node_code: + case packet_right_code: + vfp += 4; + break; + case packet_rule_code: + vfp += 8; + break; + case packet_pdf_mode: + vfp += 4; + break; + case packet_pdf_code: + vfp += 4; + /*tex Plus a string so we fall through: */ + case packet_special_code: + /*tex |+4| */ + packet_number(k); + vfp += (int) k; + break; + default: + normal_error("vf", "invalid DVI command (1)"); + } + }; + return (vfp - vf_packets); +} + +/*tex + + Typeset the \.{DVI} commands in the character packet for character |c| in + current font |f|. +*/ + +const char *packet_command_names[] = { + /*tex |slot| maps to |char| and |font| */ + "char", + "font", + "pop", + "push", + "special", + "image", + "right", + "down", + "rule", + "node", + "nop", + "end", + /*tex the next one is not (yet) supported */ + "scale", + "lua", + "pdf", + NULL +}; + +static float packet_float(eight_bits ** vfpp) +{ + unsigned int i; + union U { + float a; + eight_bits b[sizeof(float)]; + } u; + eight_bits *vfp = *vfpp; + for (i = 0; i < sizeof(float); i++) + u.b[i] = *(vfp++); + *vfpp = vfp; + return u.a; +} + +/*tex + + The |do_vf_packet| procedure is called in order to interpret the character + packet for a virtual character. Such a packet may contain the instruction to + typeset a character from the same or an other virtual font; in such cases + |do_vf_packet| calls itself recursively. The recursion level, i.e., the + number of times this has happened, is kept in the global variable + |packet_cur_s| and should not exceed |packet_max_recursion|. +*/ + +void do_vf_packet(PDF pdf, internal_font_number vf_f, int c, int ex_glyph) +{ + eight_bits *vfp; + posstructure *save_posstruct, localpos; + vf_struct *save_vfstruct, localvfstruct, *vp; + int cmd, w, mode; + unsigned k; + scaledpos size; + scaled i; + str_number s; + float f; + packet_stack_record *mat_p; + vfp = get_charinfo_packets(get_charinfo(vf_f, c)); + save_posstruct = pdf->posstruct; + /*tex use local structure for recursion */ + pdf->posstruct = &localpos; + localpos.pos = save_posstruct->pos; + /*tex invariably for vf */ + localpos.dir = dir_TLT; + save_vfstruct = pdf->vfstruct; + vp = pdf->vfstruct = &localvfstruct; + localvfstruct = *save_vfstruct; + vp->packet_stack_minlevel = ++(vp->packet_stack_level); + vp->lf = 0; + vp->fs_f = font_size(vf_f); + vp->ex_glyph = ex_glyph; + vp->packet_cur_s++; + if (vp->packet_cur_s == packet_max_recursion) + overflow("max level recursion of virtual fonts", packet_max_recursion); + vp->refpos = save_posstruct; + vp->vflua = false; + mat_p = &(vp->packet_stack[vp->packet_stack_level]); + mat_p->c0 = 1.0; + mat_p->c1 = 0.0; + mat_p->c2 = 0.0; + mat_p->c3 = 1.0; + mat_p->pos.h = 0; + mat_p->pos.v = 0; + while ((cmd = *(vfp++)) != packet_end_code) { + switch (cmd) { + case packet_font_code: + packet_number(vp->lf); + break; + case packet_push_code: + vp->packet_stack_level++; + if (vp->packet_stack_level == packet_stack_size) + normal_error("vf", "packet_stack_level overflow"); + vp->packet_stack[vp->packet_stack_level] = *mat_p; + mat_p = &(vp->packet_stack[vp->packet_stack_level]); + break; + case packet_pop_code: + if (vp->packet_stack_level == vp->packet_stack_minlevel) + normal_error("vf", "packet_stack_level underflow"); + vp->packet_stack_level--; + mat_p = &(vp->packet_stack[vp->packet_stack_level]); + break; + case packet_char_code: + packet_number(k); + /*tex We also check if |c == k| and |font(c) == font(k)| */ + if (!char_exists(vp->lf, (int) k)) { + char_warning(vp->lf, (int) k); + } else if (! ((c == k && vp->lf == vf_f)) && (has_packet(vp->lf, (int) k))) { + do_vf_packet(pdf, vp->lf, (int) k, ex_glyph); + } else { + backend_out[glyph_node] (pdf, vp->lf, (int) k, ex_glyph); + } + w = char_width(vp->lf, (int) k); + if (ex_glyph != 0 && w != 0) + w = round_xn_over_d(w, 1000 + ex_glyph, 1000); + mat_p->pos.h += w; + break; + case packet_rule_code: + packet_scaled(size.v, vp->fs_f); + packet_scaled(size.h, vp->fs_f); + if (ex_glyph != 0 && size.h > 0) + size.h = round_xn_over_d(size.h, 1000 + ex_glyph, 1000); + if (size.h > 0 && size.v > 0) + backend_out[rule_node](pdf, 0, size); + mat_p->pos.h += size.h; + break; + case packet_right_code: + packet_scaled(i, vp->fs_f); + if (ex_glyph != 0 && i != 0) + i = round_xn_over_d(i, 1000 + ex_glyph, 1000); + mat_p->pos.h += i; + break; + case packet_down_code: + packet_scaled(i, vp->fs_f); + mat_p->pos.v += i; + break; + case packet_pdf_code: + packet_number(mode); + packet_number(k); + str_room(k); + while (k > 0) { + k--; + append_char(*(vfp++)); + } + s = make_string(); + pdf_literal(pdf, s, mode, false); + flush_str(s); + break; + case packet_pdf_mode: + packet_number(mode); + pdf_literal_set_mode(pdf, mode); + break; + case packet_special_code: + packet_number(k); + str_room(k); + while (k > 0) { + k--; + append_char(*(vfp++)); + } + s = make_string(); + pdf_literal(pdf, s, scan_special, false); + flush_str(s); + break; + case packet_lua_code: + packet_number(k); + vp->vflua = true; + luacall_vf(k, vf_f, c); + /*tex + + We don't release as we (can ) flush multiple times, so no: + + \starttyping + luaL_unref(Luas, LUA_REGISTRYINDEX, k); + \stoptyping + + here! + + */ + vp->vflua = false; + break; + case packet_image_code: + packet_number(k); + vf_out_image(pdf, k); + break; + case packet_node_code: + packet_number(k); + hlist_out(pdf, (halfword) k, 0); + break; + case packet_nop_code: + break; + case packet_scale_code: + /*tex This is not yet supported in the backend. */ + f = packet_float(&vfp); + mat_p->c0 = mat_p->c0 * f; + mat_p->c3 = mat_p->c3 * f; + /* pdf->pstruct->scale = f; */ + pdf->pstruct->need_tm = true; + pdf->pstruct->need_tf = true; + break; + default: + normal_error("vf", "invalid DVI command (2)"); + } + /*tex The trivial case, always |TLT|. */ + synch_pos_with_cur(&localpos, save_posstruct, mat_p->pos); + } + pdf->posstruct = save_posstruct; + pdf->vfstruct = save_vfstruct; +} + +int *packet_local_fonts(internal_font_number f, int *num) +{ + int c, cmd, lf, k, l, i; + int localfonts[256] = { 0 }; + int *lfs; + charinfo *co; + eight_bits *vf_packets, *vfp; + k = 0; + for (c = font_bc(f); c <= font_ec(f); c++) { + if (quick_char_exists(f, c)) { + co = get_charinfo(f, c); + vfp = vf_packets = get_charinfo_packets(co); + if (vf_packets == NULL) + continue; + while ((cmd = *(vfp++)) != packet_end_code) { + switch (cmd) { + case packet_font_code: + packet_number(lf); + for (l = 0; l < k; l++) { + if (localfonts[l] == lf) { + break; + } + } + if (l == k) { + localfonts[k++] = lf; + } + break; + case packet_nop_code: + case packet_pop_code: + case packet_push_code: + break; + case packet_char_code: + case packet_down_code: + case packet_image_code: + case packet_node_code: + case packet_right_code: + vfp += 4; + break; + case packet_rule_code: + vfp += 8; + break; + case packet_special_code: + packet_number(i); + vfp += i; + break; + default: + normal_error("vf", "invalid DVI command (3)"); + } + } + } + } + *num = k; + if (k > 0) { + lfs = xmalloc((unsigned) ((unsigned) k * sizeof(int))); + memcpy(lfs, localfonts, (size_t) ((unsigned) k * sizeof(int))); + return lfs; + } + return NULL; +} + +void replace_packet_fonts(internal_font_number f, int *old_fontid, int *new_fontid, int count) +{ + int c, cmd, lf, k, l; + charinfo *co; + eight_bits *vf_packets, *vfp; + for (c = font_bc(f); c <= font_ec(f); c++) { + if (quick_char_exists(f, c)) { + co = get_charinfo(f, c); + vfp = vf_packets = get_charinfo_packets(co); + if (vf_packets == NULL) + continue; + while ((cmd = *(vfp++)) != packet_end_code) { + switch (cmd) { + case packet_font_code: + packet_number(lf); + for (l = 0; l < count; l++) { + if (old_fontid[l] == lf) { + break; + } + } + if (l < count) { + k = new_fontid[l]; + *(vfp - 4) = (eight_bits) + ((k & 0xFF000000) >> 24); + *(vfp - 3) = (eight_bits) + ((k & 0x00FF0000) >> 16); + *(vfp - 2) = (eight_bits) + ((k & 0x0000FF00) >> 8); + *(vfp - 1) = (eight_bits) (k & 0x000000FF); + } + break; + case packet_nop_code: + case packet_pop_code: + case packet_push_code: + break; + case packet_char_code: + case packet_down_code: + case packet_image_code: + case packet_node_code: + case packet_right_code: + case packet_rule_code: + vfp += 8; + break; + case packet_pdf_mode: + vfp += 4; + break; + case packet_pdf_code: + vfp += 4; + /*tex Plus a string so we fall through. */ + case packet_special_code: + packet_number(k); + vfp += k; + break; + default: + normal_error("vf", "invalid DVI command (4)"); + } + } + } + } +} diff --git a/Build/source/texk/web2c/luatexdir/font/vfpacket.w b/Build/source/texk/web2c/luatexdir/font/vfpacket.w deleted file mode 100644 index d2329916a31..00000000000 --- a/Build/source/texk/web2c/luatexdir/font/vfpacket.w +++ /dev/null @@ -1,424 +0,0 @@ -% vfpacket.w -% -% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org> -% Copyright 2006-2013 Taco Hoekwater <taco@@luatex.org> -% -% This file is part of LuaTeX. -% -% LuaTeX 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. -% -% LuaTeX 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 Lesser General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License along -% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. - -@ @c - - -#include "ptexlib.h" - -@ Some macros for processing character packets. -@c -#define packet_number(fw) { \ - fw = *(vfp++); \ - fw = fw * 256 + *(vfp++); \ - fw = fw * 256 + *(vfp++); \ - fw = fw * 256 + *(vfp++); \ -} - -#define packet_scaled(a, fs) { \ - int fw; \ - fw = *(vfp++); \ - if (fw > 127) \ - fw = fw - 256; \ - fw = fw * 256 + *(vfp++); \ - fw = fw * 256 + *(vfp++); \ - fw = fw * 256 + *(vfp++); \ - a = store_scaled_f(fw, fs); \ -} - -@ @c -vf_struct *new_vfstruct(void) -{ - vf_struct *vp = (vf_struct *) xmalloc(sizeof(vf_struct)); - vp->packet_stack_level = vp->packet_stack_minlevel = 0; - vp->packet_stack = - (packet_stack_record *) xmalloc(packet_stack_size * - sizeof(packet_stack_record)); - vp->lf = 0; - vp->fs_f = 0; - vp->packet_cur_s = 0; - vp->refpos = NULL; - vp->vflua = false; - return vp; -} - -@ Count the number of bytes in a command packet. -@c -int vf_packet_bytes(charinfo * co) -{ - eight_bits *vf_packets, *vfp; - unsigned k; - int cmd; - - vfp = vf_packets = get_charinfo_packets(co); - if (vf_packets == NULL) { - return 0; - } - while ((cmd = *(vfp++)) != packet_end_code) { - switch (cmd) { - case packet_nop_code: - case packet_pop_code: - case packet_push_code: - break; - case packet_char_code: - case packet_down_code: - case packet_font_code: - case packet_image_code: - case packet_node_code: - case packet_right_code: - case packet_rule_code: - vfp += 8; - break; - case packet_pdf_mode: - vfp += 4; - break; - case packet_pdf_code: - vfp += 4; - /* plus a string so we fall through */ - case packet_special_code: - packet_number(k); /* +4 */ - vfp += (int) k; - break; - default: - normal_error("vf", "invalid DVI command (1)"); - } - }; - return (vfp - vf_packets); -} - -@ Typeset the \.{DVI} commands in the character packet - for character |c| in current font |f|. -@c -const char *packet_command_names[] = { - "char", "font", "pop", "push", "special", "image", - "right", "down", "rule", "node", "nop", "end", "scale", "lua", "pdf", NULL -}; - -@ @c -static float packet_float(eight_bits ** vfpp) -{ - unsigned int i; - union U { - float a; - eight_bits b[sizeof(float)]; - } u; - eight_bits *vfp = *vfpp; - for (i = 0; i < sizeof(float); i++) - u.b[i] = *(vfp++); - *vfpp = vfp; - return u.a; -} - -@ The |do_vf_packet| procedure is called in order to interpret the - character packet for a virtual character. Such a packet may contain - the instruction to typeset a character from the same or an other - virtual font; in such cases |do_vf_packet| calls itself - recursively. The recursion level, i.e., the number of times this has - happened, is kept in the global variable |packet_cur_s| and should - not exceed |packet_max_recursion|. -@c -void do_vf_packet(PDF pdf, internal_font_number vf_f, int c, int ex_glyph) -{ - eight_bits *vfp; - posstructure *save_posstruct, localpos; - vf_struct *save_vfstruct, localvfstruct, *vp; - int cmd, w, mode; - unsigned k; - scaledpos size; - scaled i; - str_number s; - float f; - packet_stack_record *mat_p; - - vfp = get_charinfo_packets(get_charinfo(vf_f, c)); - assert(vfp != NULL); - - save_posstruct = pdf->posstruct; - pdf->posstruct = &localpos; /* use local structure for recursion */ - localpos.pos = save_posstruct->pos; - localpos.dir = dir_TLT; /* invariably for vf */ - - save_vfstruct = pdf->vfstruct; - vp = pdf->vfstruct = &localvfstruct; - localvfstruct = *save_vfstruct; - - vp->packet_stack_minlevel = ++(vp->packet_stack_level); - vp->lf = 0; - vp->fs_f = font_size(vf_f); - vp->ex_glyph = ex_glyph; - vp->packet_cur_s++; - if (vp->packet_cur_s == packet_max_recursion) - overflow("max level recursion of virtual fonts", packet_max_recursion); - vp->refpos = save_posstruct; - vp->vflua = false; - - mat_p = &(vp->packet_stack[vp->packet_stack_level]); - mat_p->c0 = 1.0; - mat_p->c1 = 0.0; - mat_p->c2 = 0.0; - mat_p->c3 = 1.0; - mat_p->pos.h = 0; - mat_p->pos.v = 0; - - while ((cmd = *(vfp++)) != packet_end_code) { -#ifdef DEBUG - if (cmd > packet_end_code) { - fprintf(stdout, "do_vf_packet(%i,%i) command code = illegal \n", - vf_f, c); - } else { - fprintf(stdout, "do_vf_packet(%i,%i) command code = %s\n", vf_f, c, - packet_command_names[cmd]); - } -#endif - switch (cmd) { - case packet_font_code: - packet_number(vp->lf); - break; - case packet_push_code: - vp->packet_stack_level++; - if (vp->packet_stack_level == packet_stack_size) - normal_error("vf", "packet_stack_level overflow"); - vp->packet_stack[vp->packet_stack_level] = *mat_p; - mat_p = &(vp->packet_stack[vp->packet_stack_level]); - break; - case packet_pop_code: - if (vp->packet_stack_level == vp->packet_stack_minlevel) - normal_error("vf", "packet_stack_level underflow"); - vp->packet_stack_level--; - mat_p = &(vp->packet_stack[vp->packet_stack_level]); - break; - case packet_char_code: - packet_number(k); - /* we also check if c == k and font(c) == font)k) */ - if (!char_exists(vp->lf, (int) k)) { - char_warning(vp->lf, (int) k); - } else if (! ((c == k && vp->lf == vf_f)) && (has_packet(vp->lf, (int) k))) { - do_vf_packet(pdf, vp->lf, (int) k, ex_glyph); - } else { - backend_out[glyph_node] (pdf, vp->lf, (int) k, ex_glyph); - } - w = char_width(vp->lf, (int) k); - mat_p->pos.h += round_xn_over_d(w, 1000 + ex_glyph, 1000); - break; - case packet_rule_code: - packet_scaled(size.v, vp->fs_f); /* height (where is depth?) */ - packet_scaled(size.h, vp->fs_f); - if (size.h > 0 && size.v > 0) - backend_out[rule_node](pdf, 0, size); /* the 0 is unused */ - mat_p->pos.h += size.h; - break; - case packet_right_code: - packet_scaled(i, vp->fs_f); - mat_p->pos.h += i; - break; - case packet_down_code: - packet_scaled(i, vp->fs_f); - mat_p->pos.v += i; - break; - case packet_pdf_code: - packet_number(mode); - packet_number(k); - str_room(k); - while (k > 0) { - k--; - append_char(*(vfp++)); - } - s = make_string(); - pdf_literal(pdf, s, mode, false); - flush_str(s); - break; - case packet_pdf_mode: - packet_number(mode); - pdf_literal_set_mode(pdf, mode); - break; - case packet_special_code: - packet_number(k); - str_room(k); - while (k > 0) { - k--; - append_char(*(vfp++)); - } - s = make_string(); - pdf_literal(pdf, s, scan_special, false); - flush_str(s); - break; - case packet_lua_code: - packet_number(k); - vp->vflua = true; - if (luaL_loadbuffer - (Luas, (const char *) vfp, (size_t) k, "packet_lua_code") - || lua_pcall(Luas, 0, LUA_MULTRET, 0)) - lua_error(Luas); - vp->vflua = false; - vfp += k; - break; - case packet_image_code: - packet_number(k); - vf_out_image(pdf, k); - break; - case packet_node_code: - packet_number(k); - hlist_out(pdf, (halfword) k, 0); - break; - case packet_nop_code: - break; - case packet_scale_code: - f = packet_float(&vfp); - mat_p->c0 = mat_p->c0 * f; - mat_p->c3 = mat_p->c3 * f; - /* pdf->pstruct->scale = f; *//* scale is still NOP */ - pdf->pstruct->need_tm = true; - pdf->pstruct->need_tf = true; - break; - default: - normal_error("vf", "invalid DVI command (2)"); - } - synch_pos_with_cur(&localpos, save_posstruct, mat_p->pos); /* trivial case, always TLT */ - } - pdf->posstruct = save_posstruct; - pdf->vfstruct = save_vfstruct; -} - -@ @c -int *packet_local_fonts(internal_font_number f, int *num) -{ - int c, cmd, lf, k, l, i; - int localfonts[256] = { 0 }; - int *lfs; - charinfo *co; - - eight_bits *vf_packets, *vfp; - k = 0; - for (c = font_bc(f); c <= font_ec(f); c++) { - if (quick_char_exists(f, c)) { - co = get_charinfo(f, c); - vfp = vf_packets = get_charinfo_packets(co); - if (vf_packets == NULL) - continue; - while ((cmd = *(vfp++)) != packet_end_code) { - switch (cmd) { - case packet_font_code: - packet_number(lf); - for (l = 0; l < k; l++) { - if (localfonts[l] == lf) { - break; - } - } - if (l == k) { - localfonts[k++] = lf; - } - break; - case packet_nop_code: - case packet_pop_code: - case packet_push_code: - break; - case packet_char_code: - case packet_down_code: - case packet_image_code: - case packet_node_code: - case packet_right_code: - vfp += 4; - break; - case packet_rule_code: - vfp += 8; - break; - case packet_special_code: - packet_number(i); - vfp += i; - break; - default: - normal_error("vf", "invalid DVI command (3)"); - } - } - } - } - *num = k; - if (k > 0) { - lfs = xmalloc((unsigned) ((unsigned) k * sizeof(int))); - memcpy(lfs, localfonts, (size_t) ((unsigned) k * sizeof(int))); - return lfs; - } - return NULL; -} - -@ @c -void -replace_packet_fonts(internal_font_number f, int *old_fontid, - int *new_fontid, int count) -{ - int c, cmd, lf, k, l; - charinfo *co; - eight_bits *vf_packets, *vfp; - - for (c = font_bc(f); c <= font_ec(f); c++) { - if (quick_char_exists(f, c)) { - co = get_charinfo(f, c); - vfp = vf_packets = get_charinfo_packets(co); - if (vf_packets == NULL) - continue; - while ((cmd = *(vfp++)) != packet_end_code) { - switch (cmd) { - case packet_font_code: - packet_number(lf); - for (l = 0; l < count; l++) { - if (old_fontid[l] == lf) { - break; - } - } - if (l < count) { - k = new_fontid[l]; - *(vfp - 4) = (eight_bits) - ((k & 0xFF000000) >> 24); - *(vfp - 3) = (eight_bits) - ((k & 0x00FF0000) >> 16); - *(vfp - 2) = (eight_bits) - ((k & 0x0000FF00) >> 8); - *(vfp - 1) = (eight_bits) (k & 0x000000FF); - } - break; - case packet_nop_code: - case packet_pop_code: - case packet_push_code: - break; - case packet_char_code: - case packet_down_code: - case packet_image_code: - case packet_node_code: - case packet_right_code: - case packet_rule_code: - vfp += 8; - break; - case packet_pdf_mode: - vfp += 4; - break; - case packet_pdf_code: - vfp += 4; - /* plus a string so we fall through */ - case packet_special_code: - packet_number(k); - vfp += k; - break; - default: - normal_error("vf", "invalid DVI command (4)"); - } - } - } - } -} diff --git a/Build/source/texk/web2c/luatexdir/font/writecff.w b/Build/source/texk/web2c/luatexdir/font/writecff.c index a71e16f6f5c..e6570e070c6 100644 --- a/Build/source/texk/web2c/luatexdir/font/writecff.w +++ b/Build/source/texk/web2c/luatexdir/font/writecff.c @@ -1,23 +1,23 @@ -% writecff.w -% -% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org> -% -% This file is part of LuaTeX. -% -% LuaTeX 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. -% -% LuaTeX 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 Lesser General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License along -% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. - -@ @c +/* + +Copyright 2006-2010 Taco Hoekwater <taco@luatex.org> + +This file is part of LuaTeX. + +LuaTeX 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. + +LuaTeX 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU General Public License along +with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +*/ #include "ptexlib.h" #include "lua/luatex-api.h" @@ -25,7 +25,6 @@ extern int cidset; -@ @c #define get_offset(s,n) get_unsigned(s, (n)) #define get_card8(a) (card8)(a->stream[a->offset++]) #define get_card16(a) (card16)(get_unsigned(a,2)) @@ -48,8 +47,6 @@ static unsigned long get_unsigned(cff_font * cff, int n) return v; } -@ @c - const char *const cff_stdstr[CFF_STDSTR_MAX] = { ".notdef", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quoteright", "parenleft", @@ -146,8 +143,8 @@ const char *const cff_stdstr[CFF_STDSTR_MAX] = { "Black", "Bold", "Book", "Light", "Medium", "Regular", "Roman", "Semibold" }; -@ Only read header part but not body -@c +/*tex Only read the header part and forget about the body */ + cff_index *cff_get_index_header(cff_font * cff) { cff_index *idx; @@ -179,7 +176,6 @@ cff_index *cff_get_index_header(cff_font * cff) return idx; } -@ @c cff_index *cff_get_index(cff_font * cff) { cff_index *idx; @@ -222,29 +218,22 @@ static cff_index *cff_empty_index(cff_font * cff) static cff_index *cff_get_index2(cff_font * cff) { - /* we fake a dict array */ - + /*tex We fake a dict array. */ cff_index *idx; size_t length; - idx = xcalloc(1, sizeof(cff_index)); - length = (size_t) cff->header_offsize; - idx->offsize = 2; idx->count = 1; idx->offset = xmalloc((unsigned) (((unsigned) 2) * sizeof(l_offset))); - idx->offset[0] = 1; // get_offset(cff, idx->offsize); - idx->offset[1] = length + 1; // idx->offset[0] + length; - + idx->offset[0] = 1; + idx->offset[1] = length + 1; idx->data = xmalloc((unsigned) length * sizeof(card8)); memcpy(idx->data, &cff->stream[cff->offset], length ); cff->offset += length ; - return idx; } -@ @c long cff_pack_index(cff_index * idx, card8 * dest, long destlen) { long len = 0; @@ -297,7 +286,6 @@ long cff_pack_index(cff_index * idx, card8 * dest, long destlen) return len; } -@ @c long cff_index_size(cff_index * idx) { if (idx->count > 0) { @@ -318,7 +306,6 @@ long cff_index_size(cff_index * idx) } } -@ @c cff_index *cff_new_index(card16 count) { cff_index *idx; @@ -335,7 +322,6 @@ cff_index *cff_new_index(card16 count) return idx; } -@ @c void cff_release_index(cff_index * idx) { if (idx) { @@ -345,7 +331,6 @@ void cff_release_index(cff_index * idx) } } -@ @c void cff_release_dict(cff_dict * dict) { if (dict) { @@ -360,7 +345,6 @@ void cff_release_dict(cff_dict * dict) } } -@ @c void cff_release_encoding(cff_encoding * encoding) { if (encoding) { @@ -380,7 +364,6 @@ void cff_release_encoding(cff_encoding * encoding) } } -@ @c void cff_release_charsets(cff_charsets * charset) { if (charset) { @@ -401,7 +384,6 @@ void cff_release_charsets(cff_charsets * charset) } } -@ @c void cff_release_fdselect(cff_fdselect * fdselect) { if (fdselect) { @@ -414,7 +396,6 @@ void cff_release_fdselect(cff_fdselect * fdselect) } } -@ @c void cff_close(cff_font * cff) { card16 i; @@ -464,7 +445,6 @@ void cff_close(cff_font * cff) return; } -@ @c char *cff_get_name(cff_font * cff) { char *fontname; @@ -478,7 +458,6 @@ char *cff_get_name(cff_font * cff) return fontname; } -@ @c long cff_set_name(cff_font * cff, char *name) { cff_index *idx; @@ -493,7 +472,8 @@ long cff_set_name(cff_font * cff, char *name) (idx->offset)[0] = 1; (idx->offset)[1] = strlen(name) + 1; idx->data = xmalloc((unsigned) strlen(name) * sizeof(card8)); - memmove(idx->data, name, strlen(name)); /* no trailing |'\0'| */ + /*tex No trailing |\0| */ + memmove(idx->data, name, strlen(name)); return (long) (5 + strlen(name)); } @@ -501,23 +481,21 @@ long cff_put_header(cff_font * cff, card8 * dest, long destlen) { if (destlen < 4) normal_error("cff","not enough space available"); - - *(dest++) = 1; /* cff->header_major; */ + /*tex cff->header_major */ + *(dest++) = 1; *(dest++) = cff->header_minor; *(dest++) = 4; - /* - Additional data in between header and Name INDEX is ignored. - - We will set all offset (0) to a four-byte integer. + /*tex + Additional data in between header and Name INDEX is ignored. We will set + all offset (0) to a four-byte integer. */ *(dest++) = 4; cff->header_offsize = 4; return 4; } -@ @c -#define CFF_PARSE_OK 0 -#define CFF_CFF_ERROR_PARSE_CFF_ERROR -1 +#define CFF_PARSE_OK 0 +#define CFF_CFF_ERROR_PARSE_CFF_ERROR -1 #define CFF_CFF_ERROR_STACK_OVERFLOW -2 #define CFF_CFF_ERROR_STACK_UNDERFLOW -3 #define CFF_CFF_ERROR_STACK_RANGECHECK -4 @@ -534,22 +512,27 @@ cff_dict *cff_new_dict(void) return dict; } -@ Operand stack: only numbers are stored (as double). Operand types are: +/*tex + + Operand stack: only numbers are stored (as double). Operand types are: -\item number: double (integer or real) -\item boolean: stored as a number -\item SID: stored as a number -\item array: array of numbers -\item delta: array of numbers + \startitemize + \startitem number: double (integer or real) \stopitem + \startitem boolean: stored as a number \stopitem + \startitem SID: stored as a number \stopitem + \startitem array: array of numbers \stopitem + \startitem delta: array of numbers \stopitem + \stopitemize + +*/ -@c #define CFF_DICT_STACK_LIMIT 64 static int stack_top = 0; static double arg_stack[CFF_DICT_STACK_LIMIT]; -@ CFF DICT encoding. -@c -#define CFF_LAST_DICT_OP1 26 /* 22 */ +/* The CFF DICT encoding: */ + +#define CFF_LAST_DICT_OP1 26 #define CFF_LAST_DICT_OP2 39 #define CFF_LAST_DICT_OP (CFF_LAST_DICT_OP1 + CFF_LAST_DICT_OP2) @@ -569,21 +552,22 @@ static struct { { "FamilyOtherBlues", CFF_TYPE_DELTA }, { "StdHW", CFF_TYPE_NUMBER }, { "StdVW", CFF_TYPE_NUMBER }, - { NULL, -1 }, /* first byte of two-byte operator 12 */ + { NULL, -1 }, { "UniqueID", CFF_TYPE_NUMBER }, { "XUID", CFF_TYPE_ARRAY }, { "charset", CFF_TYPE_OFFSET }, { "Encoding", CFF_TYPE_OFFSET }, { "CharStrings", CFF_TYPE_OFFSET }, - { "Private", CFF_TYPE_SZOFF }, /* two numbers (size and offset) */ + { "Private", CFF_TYPE_SZOFF }, { "Subrs", CFF_TYPE_OFFSET }, { "defaultWidthX", CFF_TYPE_NUMBER }, { "nominalWidthX", CFF_TYPE_NUMBER }, { NULL, -1 }, { NULL, -1 }, - { "vstore", CFF_TYPE_OFFSET }, /* cff2 */ - { "maxstack", CFF_TYPE_NUMBER }, /* cff2 */ - /* Here we start with operator 2 of 12 */ + /*tex two CFF2 instructions */ + { "vstore", CFF_TYPE_OFFSET }, + { "maxstack", CFF_TYPE_NUMBER }, + /*tex Here we start with operator 2 of 12. */ { "Copyright", CFF_TYPE_SID }, { "IsFixedPitch", CFF_TYPE_BOOLEAN }, { "ItalicAngle", CFF_TYPE_NUMBER }, @@ -625,21 +609,23 @@ static struct { { "FontName", CFF_TYPE_SID } }; -@ Parse DICT data -@c +/*tex Parse DICT data */ + static double get_integer(card8 ** data, card8 * endptr, int *status) { long result = 0; card8 b0, b1, b2; b0 = *(*data)++; - if (b0 == 28 && *data < endptr - 2) { /* shortint */ + if (b0 == 28 && *data < endptr - 2) { + /*tex shortint */ b1 = *(*data)++; b2 = *(*data)++; result = b1 * 256 + b2; if (result > 0x7fffL) result -= 0x10000L; - } else if (b0 == 29 && *data < endptr - 4) { /* longint */ + } else if (b0 == 29 && *data < endptr - 4) { + /*tex longint */ int i; result = *(*data)++; if (result > 0x7f) @@ -648,9 +634,11 @@ static double get_integer(card8 ** data, card8 * endptr, int *status) result = result * 256 + (**data); *data += 1; } - } else if (b0 >= 32 && b0 <= 246) { /* int (1) */ + } else if (b0 >= 32 && b0 <= 246) { + /*tex int (1) */ result = b0 - 139; - } else if (b0 >= 247 && b0 <= 250) { /* int (2) */ + } else if (b0 >= 247 && b0 <= 250) { + /*tex int (2) */ b1 = *(*data)++; result = (b0 - 247) * 256 + b1 + 108; } else if (b0 >= 251 && b0 <= 254) { @@ -659,12 +647,11 @@ static double get_integer(card8 ** data, card8 * endptr, int *status) } else { *status = CFF_CFF_ERROR_PARSE_CFF_ERROR; } - return (double) result; } -@ Simply uses strtod -@c +/*tex Simply uses |strtod|: */ + static double get_real(card8 ** data, card8 * endptr, int *status) { double result = 0.0; @@ -675,12 +662,11 @@ static double get_real(card8 ** data, card8 * endptr, int *status) *status = CFF_CFF_ERROR_PARSE_CFF_ERROR; return 0.0; } - - *data += 1; /* skip first byte (30) */ - + /*tex Skip the first byte (30): */ + *data += 1; pos = 0; while ((!fail) && len < WORK_BUFFER_SIZE - 2 && *data < endptr) { - /* get nibble */ + /*tex Get a nibble. */ if (pos % 2) { nibble = **data & 0x0f; *data += 1; @@ -691,52 +677,49 @@ static double get_real(card8 ** data, card8 * endptr, int *status) work_buffer[len++] = (char) (nibble + '0'); } else if (nibble == 0x0a) { /* . */ work_buffer[len++] = '.'; - } else if (nibble == 0x0b || nibble == 0x0c) { /* E, E- */ + } else if (nibble == 0x0b || nibble == 0x0c) { + /*tex E, E- */ work_buffer[len++] = 'e'; if (nibble == 0x0c) work_buffer[len++] = '-'; - } else if (nibble == 0x0e) { /* `-' */ + } else if (nibble == 0x0e) { + /*tex the minus */ work_buffer[len++] = '-'; - } else if (nibble == 0x0d) { /* skip */ - /* do nothing */ - } else if (nibble == 0x0f) { /* end */ + } else if (nibble == 0x0d) { + /*tex do nothing */ + } else if (nibble == 0x0f) { + /*tex we're done */ work_buffer[len++] = '\0'; if (((pos % 2) == 0) && (**data != 0xff)) { fail = 1; } break; - } else { /* invalid */ + } else { + /*tex invalid */ fail = 1; } pos++; } - - /* returned values */ + /*tex the returned values */ if (fail || nibble != 0x0f) { *status = CFF_CFF_ERROR_PARSE_CFF_ERROR; } else { char *s; - /* strtod sets errno for OVERFLOW and _maybe_ UNDERFLOW */ - /* but not for an invalid conversion (as for example if we try to convert "foo" in a double )*/ - /* At least in glib sets errno also for UNDERFLOW */ - /* We don't save/restore the prev. errno */ errno=0; result = strtod(work_buffer, &s); - if ( (result==0.0 && work_buffer==s) || errno ) { - /* conversion is not possible */ + if ((result==0.0 && work_buffer==s) || errno) { + /*tex Conversion is not possible. */ *status = CFF_CFF_ERROR_PARSE_CFF_ERROR; } } return result; } -@ operators -@c -static void add_dict(cff_dict * dict, - card8 ** data, card8 * endptr, int *status) +/*tex Operators */ + +static void add_dict(cff_dict * dict, card8 ** data, card8 * endptr, int *status) { int id, argtype, t; - id = **data; if (id == 0x0c) { *data += 1; @@ -749,28 +732,22 @@ static void add_dict(cff_dict * dict, *status = CFF_CFF_ERROR_PARSE_CFF_ERROR; return; } - argtype = dict_operator[id].argtype; if (dict_operator[id].opname == NULL || argtype < 0) { *status = CFF_CFF_ERROR_PARSE_CFF_ERROR; return; } - if (dict->count >= dict->max) { dict->max += DICT_ENTRY_MAX; - /* not zeroed! */ - dict->entries = - xrealloc(dict->entries, - (unsigned) ((unsigned) dict->max * - sizeof(cff_dict_entry))); + /*tex Not zeroed! */ + dict->entries = xrealloc(dict->entries, (unsigned) ((unsigned) dict->max * sizeof(cff_dict_entry))); } - (dict->entries)[dict->count].id = id; (dict->entries)[dict->count].key = dict_operator[id].opname; if (argtype == CFF_TYPE_NUMBER || argtype == CFF_TYPE_BOOLEAN || argtype == CFF_TYPE_SID || argtype == CFF_TYPE_OFFSET) { - /* check for underflow here, as exactly one operand is expected */ + /*tex Check for underflow here, as exactly one operand is expected. */ if (stack_top < 1) { *status = CFF_CFF_ERROR_STACK_UNDERFLOW; return; @@ -781,8 +758,10 @@ static void add_dict(cff_dict * dict, (dict->entries)[dict->count].values[0] = arg_stack[stack_top]; dict->count += 1; } else { - /* just ignore operator if there were no operands provided; - don't treat this as underflow (e.g. StemSnapV in TemporaLGCUni-Italic.otf) */ + /*tex + Just ignore operator if there were no operands provided. Don't treat + this as underflow, e.g. |StemSnapV| in |TemporaLGCUni-Italic.otf|. + */ if ((t = stack_top) > 0) { (dict->entries)[dict->count].count = stack_top; (dict->entries)[dict->count].values = @@ -793,26 +772,27 @@ static void add_dict(cff_dict * dict, arg_stack[stack_top]; } if (t > 3 && strcmp(dict_operator[id].opname, "FontMatrix") == 0) { - /* reset FontMatrix to [0.001 * * 0.001 * *], - fix mantis bug \# 0000200 (acroread "feature") */ (dict->entries)[dict->count].values[0] = 0.001; (dict->entries)[dict->count].values[3] = 0.001; } dict->count += 1; } } - *data += 1; - return; } +/*tex + + All operands are treated as number or array of numbers. -@ All operands are treated as number or array of numbers. - Private: two numbers, size and offset - ROS : three numbers, SID, SID, and a number + \startitemize + \startitem |Private|: two numbers, size and offset \stopitem + \startitem |ROS|: hree numbers, SID, SID, and a number \stopitem + \stopitemize + +*/ -@c cff_dict *cff_dict_unpack(card8 * data, card8 * endptr) { cff_dict *dict; @@ -820,18 +800,22 @@ cff_dict *cff_dict_unpack(card8 * data, card8 * endptr) stack_top = 0; dict = cff_new_dict(); while (data < endptr && status == CFF_PARSE_OK) { - if (*data < CFF_LAST_DICT_OP1) { /* operator */ + if (*data < CFF_LAST_DICT_OP1) { + /*tex Some operator. */ add_dict(dict, &data, endptr, &status); - } else if (*data == 30) { /* real - First byte of a sequence (variable) */ + } else if (*data == 30) { + /*tex First byte of a sequence (variable). */ if (stack_top < CFF_DICT_STACK_LIMIT) { arg_stack[stack_top] = get_real(&data, endptr, &status); stack_top++; } else { status = CFF_CFF_ERROR_STACK_OVERFLOW; } - } else if (*data == 255 || (*data >= CFF_LAST_DICT_OP1 && *data <= 27)) { /* reserved */ + } else if (*data == 255 || (*data >= CFF_LAST_DICT_OP1 && *data <= 27)) { + /*tex Reserved. */ data++; - } else { /* everything else are integer */ + } else { + /*tex Everything else is an integer. */ if (stack_top < CFF_DICT_STACK_LIMIT) { arg_stack[stack_top] = get_integer(&data, endptr, &status); stack_top++; @@ -849,7 +833,6 @@ cff_dict *cff_dict_unpack(card8 * data, card8 * endptr) return dict; } -@ @c int cff_dict_known(cff_dict * dict, const char *key) { int i; @@ -861,7 +844,6 @@ int cff_dict_known(cff_dict * dict, const char *key) return 0; } -@ @c double cff_dict_get(cff_dict * dict, const char *key, int idx) { double value = 0.0; @@ -881,72 +863,59 @@ double cff_dict_get(cff_dict * dict, const char *key, int idx) return value; } -@ @c card8 cff_fdselect_lookup(cff_font * cff, card16 gid) { card8 fd = 0xff; cff_fdselect *fdsel; - if (cff->fdselect == NULL) normal_error("cff","FDSelect not available"); - fdsel = cff->fdselect; - if (gid >= cff->num_glyphs) normal_error("cff","invalid glyph index"); - switch (fdsel->format) { - case 0: - fd = fdsel->data.fds[gid]; - break; - case 3: - { - if (gid == 0) { - fd = (fdsel->data).ranges[0].fd; - } else { - card16 i; - for (i = 1; i < (fdsel->num_entries); i++) { - if (gid < (fdsel->data).ranges[i].first) - break; + case 0: + fd = fdsel->data.fds[gid]; + break; + case 3: + { + if (gid == 0) { + fd = (fdsel->data).ranges[0].fd; + } else { + card16 i; + for (i = 1; i < (fdsel->num_entries); i++) { + if (gid < (fdsel->data).ranges[i].first) + break; + } + fd = (fdsel->data).ranges[i - 1].fd; } - fd = (fdsel->data).ranges[i - 1].fd; } - } - break; - default: - normal_error("cff","invalid FDSelect format"); - break; + break; + default: + normal_error("cff","invalid FDSelect format"); + break; } - if (fd >= cff->num_fds) normal_error("cff","invalid Font DICT index"); - return fd; } -@ @c long cff_read_subrs(cff_font * cff) { long len = 0; long offset; int i; - if ((cff->flag & FONTTYPE_CIDFONT) && cff->fdselect == NULL) { cff_read_fdselect(cff); } - if ((cff->flag & FONTTYPE_CIDFONT) && cff->fdarray == NULL) { cff_read_fdarray(cff); } - if (cff->private == NULL) cff_read_private(cff); - if (cff->gsubr == NULL) { cff->offset = cff->gsubr_offset; cff->gsubr = cff_get_index(cff); } - cff->subrs = xcalloc(cff->num_fds, sizeof(cff_index *)); if (cff->flag & FONTTYPE_CIDFONT) { for (i = 0; i < cff->num_fds; i++) { @@ -970,25 +939,19 @@ long cff_read_subrs(cff_font * cff) (cff->subrs)[0] = cff_get_index(cff); len += cff_index_size((cff->subrs)[0]); } - return len; } -@ @c long cff_read_fdarray(cff_font * cff) { long len = 0; cff_index *idx; long offset, size; card16 i; - if (cff->topdict == NULL) normal_error("cff","top DICT not found"); - if (!(cff->flag & FONTTYPE_CIDFONT)) return 0; - - /* must exist */ offset = (long) cff_dict_get(cff->topdict, "FDArray", 0); cff->offset = (l_offset) offset; idx = cff_get_index(cff); @@ -1005,24 +968,18 @@ long cff_read_fdarray(cff_font * cff) } len = cff_index_size(idx); cff_release_index(idx); - return len; } - -@ @c long cff_read_private(cff_font * cff) { long len = 0; card8 *data; long offset, size; - if (cff->flag & FONTTYPE_CIDFONT) { int i; - if (cff->fdarray == NULL) cff_read_fdarray(cff); - cff->private = xmalloc((unsigned) (cff->num_fds * sizeof(cff_dict *))); for (i = 0; i < cff->num_fds; i++) { if (cff->fdarray[i] != NULL && @@ -1058,29 +1015,23 @@ long cff_read_private(cff_font * cff) len = 0; } } - return len; } - -@ @c cff_font *read_cff(unsigned char *buf, long buflength, int n) { cff_font *cff; cff_index *idx; long offset; - cff = xcalloc(1, sizeof(cff_font)); - cff->stream = buf; cff->stream_size = (l_offset) buflength; cff->index = n; - cff->header_major = get_card8(cff); cff->header_minor = get_card8(cff); cff->header_hdr_size = get_card8(cff); if (cff->header_major == 2) { - /* we have only one top dictionary */ + /*tex We have only one top dictionary. */ cff->header_offsize = get_card16(cff); } else { cff->header_offsize = get_card8(cff); @@ -1096,8 +1047,7 @@ cff_font *read_cff(unsigned char *buf, long buflength, int n) return NULL; } cff->offset = cff->header_hdr_size; - - /* Name INDEX */ + /*tex The name index. */ if (cff->header_major == 2) { cff->name = cff_empty_index(cff); } else { @@ -1110,65 +1060,55 @@ cff_font *read_cff(unsigned char *buf, long buflength, int n) cff->name = idx; cff->fontname = cff_get_name(cff); } - - /* Top DICT INDEX */ + /*tex The top dict index. */ if (cff->header_major == 2) { - /* we fake an index (just one entry) */ + /*tex we fake an index (just one entry) */ idx = cff_get_index2(cff); } else { idx = cff_get_index(cff); } - if (n > idx->count - 1) { normal_warning("cff","top DICT not exist"); cff_close(cff); return NULL; } - cff->topdict = cff_dict_unpack(idx->data + idx->offset[n] - 1, - idx->data + idx->offset[n + 1] - 1); + cff->topdict = cff_dict_unpack(idx->data + idx->offset[n] - 1, idx->data + idx->offset[n + 1] - 1); if (!cff->topdict) { normal_warning("cff","parsing top DICT data failed"); cff_close(cff); return NULL; } cff_release_index(idx); - if (cff_dict_known(cff->topdict, "CharstringType") && cff_dict_get(cff->topdict, "CharstringType", 0) != 2) { normal_warning("cff","only type 2 charstrings supported"); cff_close(cff); return NULL; } - if (cff_dict_known(cff->topdict, "SyntheticBase")) { normal_warning("cff","synthetic font not supported"); cff_close(cff); return NULL; } - - /* String INDEX */ + /*tex The string index. */ if (cff->header_major == 2) { - // cff->string = cff_empty_index(cff); + /*tex do nothing */ } else { cff->string = cff_get_index(cff); } - - /* offset to GSubr */ + /*tex The offset to subroutines. */ cff->gsubr_offset = cff->offset; - - /* Number of glyphs */ + /*tex The number of glyphs. */ offset = (long) cff_dict_get(cff->topdict, "CharStrings", 0); cff->offset = (l_offset) offset; cff->num_glyphs = get_card16(cff); - - /* Check for font type */ + /*tex Check for font type. */ if (cff_dict_known(cff->topdict, "ROS")) { cff->flag |= FONTTYPE_CIDFONT; } else { cff->flag |= FONTTYPE_FONT; } - - /* Check for encoding */ + /*tex Check for the encoding. */ if (cff_dict_known(cff->topdict, "Encoding")) { offset = (long) cff_dict_get(cff->topdict, "Encoding", 0); if (offset == 0) { /* predefined */ @@ -1179,20 +1119,15 @@ cff_font *read_cff(unsigned char *buf, long buflength, int n) } else { cff->flag |= ENCODING_STANDARD; } - - cff->offset = cff->gsubr_offset; /* seek back to GSubr */ - + cff->offset = cff->gsubr_offset; return cff; } -@* write a cff for opentype. +/*tex Write CFF data for an \OPENTYPE\ font. We need to pack dictionary data. */ -@ Pack DICT data -@c static long pack_integer(card8 * dest, long destlen, long value) { long len = 0; - if (value >= -107 && value <= 107) { if (destlen < 1) normal_error("cff","buffer overflow (1)"); @@ -1212,14 +1147,16 @@ static long pack_integer(card8 * dest, long destlen, long value) dest[0] = (card8) ((value >> 8) & 0xff); dest[1] = (card8) (value & 0xff); len = 2; - } else if (value >= -32768 && value <= 32767) { /* shortint */ + } else if (value >= -32768 && value <= 32767) { + /*tex shortint */ if (destlen < 3) normal_error("cff","buffer overflow (4)"); dest[0] = 28; dest[1] = (card8) ((value >> 8) & 0xff); dest[2] = (card8) (value & 0xff); len = 3; - } else { /* longint */ + } else { + /*tex longint */ if (destlen < 5) normal_error("cff","buffer overflow (5)"); dest[0] = 29; @@ -1232,30 +1169,24 @@ static long pack_integer(card8 * dest, long destlen, long value) return len; } -@ @c static long pack_real(card8 * dest, long destlen, double value) { long e; int i = 0, pos = 2; int res; #define CFF_REAL_MAX_LEN 17 - if (destlen < 2) normal_error("cff","buffer overflow (6)"); - dest[0] = 30; - if (value == 0.0) { dest[1] = 0x0f; return 2; } - if (value < 0.0) { dest[1] = 0xe0; value *= -1.0; pos++; } - e = 0; if (value >= 10.0) { while (value >= 10.0) { @@ -1268,17 +1199,15 @@ static long pack_real(card8 * dest, long destlen, double value) e--; } } - - res=sprintf(work_buffer, "%1.14g", value); - if (res<0) normal_error("cff","invalid conversion"); - if (res>CFF_REAL_MAX_LEN) res=CFF_REAL_MAX_LEN; - + res = sprintf(work_buffer, "%1.14g", value); + if (res<0) + normal_error("cff","invalid conversion"); + if (res>CFF_REAL_MAX_LEN) + res=CFF_REAL_MAX_LEN; for (i = 0; i < res; i++) { unsigned char ch = 0; - if (work_buffer[i] == '\0') { - /* res should prevent this. */ - /* normal_error("cff","cannot happen"); */ + /*tex In fact |res| should prevent this. */ break; } else if (work_buffer[i] == '.') { ch = 0x0a; @@ -1287,7 +1216,6 @@ static long pack_real(card8 * dest, long destlen, double value) } else { normal_error("cff","invalid character"); } - if (destlen < pos / 2 + 1) normal_error("cff","buffer overflow (7)"); @@ -1298,7 +1226,6 @@ static long pack_real(card8 * dest, long destlen, double value) } pos++; } - if (e > 0) { if (pos % 2) { dest[pos / 2] = (card8) (dest[pos / 2] + 0x0b); @@ -1319,7 +1246,6 @@ static long pack_real(card8 * dest, long destlen, double value) e *= -1; pos++; } - if (e != 0) { sprintf(work_buffer, "%ld", e); for (i = 0; i < CFF_REAL_MAX_LEN; i++) { @@ -1333,10 +1259,8 @@ static long pack_real(card8 * dest, long destlen, double value) } else { normal_error("cff","invalid character"); } - if (destlen < pos / 2 + 1) normal_error("cff","buffer overflow (10)"); - if (pos % 2) { dest[pos / 2] = (card8) (dest[pos / 2] + ch); } else { @@ -1345,7 +1269,6 @@ static long pack_real(card8 * dest, long destlen, double value) pos++; } } - if (pos % 2) { dest[pos / 2] = (card8) (dest[pos / 2] + 0x0f); pos++; @@ -1355,19 +1278,14 @@ static long pack_real(card8 * dest, long destlen, double value) dest[pos / 2] = (card8) (0xff); pos += 2; } - return pos / 2; } -@ @c -static long cff_dict_put_number(double value, - card8 * dest, long destlen, int type) +static long cff_dict_put_number(double value, card8 * dest, long destlen, int type) { long len = 0; double nearint; - nearint = floor(value + 0.5); - /* set offset to longint */ if (type == CFF_TYPE_OFFSET) { long lvalue; lvalue = (long) value; @@ -1379,21 +1297,20 @@ static long cff_dict_put_number(double value, dest[3] = (card8) ((lvalue >> 8) & 0xff); dest[4] = (card8) (lvalue & 0xff); len = 5; - } else if (value > CFF_INT_MAX || value < CFF_INT_MIN || (fabs(value - nearint) > 1.0e-5)) { /* real */ + } else if (value > CFF_INT_MAX || value < CFF_INT_MIN || (fabs(value - nearint) > 1.0e-5)) { + /*tex A real */ len = pack_real(dest, destlen, value); - } else { /* integer */ + } else { + /*tex An integer */ len = pack_integer(dest, destlen, (long) nearint); } - return len; } -@ @c static long put_dict_entry(cff_dict_entry * de, card8 * dest, long destlen) { long len = 0; int i, type, id; - if (de->count > 0) { id = de->id; if (dict_operator[id].argtype == CFF_TYPE_OFFSET || @@ -1418,16 +1335,13 @@ static long put_dict_entry(cff_dict_entry * de, card8 * dest, long destlen) normal_error("cff","invalid DICT operator ID"); } } - return len; } -@ @c long cff_dict_pack(cff_dict * dict, card8 * dest, long destlen) { long len = 0; int i; - for (i = 0; i < dict->count; i++) { if (!strcmp(dict->entries[i].key, "ROS")) { len += put_dict_entry(&dict->entries[i], dest, destlen); @@ -1439,24 +1353,19 @@ long cff_dict_pack(cff_dict * dict, card8 * dest, long destlen) len += put_dict_entry(&dict->entries[i], dest + len, destlen - len); } } - return len; } -@ @c void cff_dict_add(cff_dict * dict, const char *key, int count) { int id, i; - for (id = 0; id < CFF_LAST_DICT_OP; id++) { if (key && dict_operator[id].opname && strcmp(dict_operator[id].opname, key) == 0) break; } - if (id == CFF_LAST_DICT_OP) normal_error("cff","unknown DICT operator"); - for (i = 0; i < dict->count; i++) { if ((dict->entries)[i].id == id) { if ((dict->entries)[i].count != count) @@ -1464,30 +1373,23 @@ void cff_dict_add(cff_dict * dict, const char *key, int count) return; } } - if (dict->count + 1 >= dict->max) { dict->max += 8; dict->entries = - xrealloc(dict->entries, - (unsigned) ((unsigned) dict->max * - sizeof(cff_dict_entry))); + xrealloc(dict->entries, (unsigned) ((unsigned) dict->max * sizeof(cff_dict_entry))); } - (dict->entries)[dict->count].id = id; (dict->entries)[dict->count].key = dict_operator[id].opname; (dict->entries)[dict->count].count = count; if (count > 0) { - (dict->entries)[dict->count].values = - xcalloc((unsigned) count, sizeof(double)); + (dict->entries)[dict->count].values = xcalloc((unsigned) count, sizeof(double)); } else { (dict->entries)[dict->count].values = NULL; } dict->count += 1; - return; } -@ @c void cff_dict_remove(cff_dict * dict, const char *key) { int i; @@ -1499,13 +1401,9 @@ void cff_dict_remove(cff_dict * dict, const char *key) } } -@ @c void cff_dict_set(cff_dict * dict, const char *key, int idx, double value) { int i; - - assert(dict && key); - for (i = 0; i < dict->count; i++) { if (strcmp(key, (dict->entries)[i].key) == 0) { if ((dict->entries)[i].count > idx) @@ -1515,19 +1413,17 @@ void cff_dict_set(cff_dict * dict, const char *key, int idx, double value) break; } } - if (i == dict->count) formatted_error("cff","DICT entry '%s' not found", key); } -@ Strings -@c +/*tex Strings */ + char *cff_get_string(cff_font * cff, s_SID id) { char *result = NULL; size_t len; - if (id < CFF_STDSTR_MAX) { len = strlen(cff_stdstr[id]); result = xmalloc((unsigned) (len + 1) * sizeof(char)); @@ -1543,19 +1439,15 @@ char *cff_get_string(cff_font * cff, s_SID id) result[len] = '\0'; } } - return result; } -@ @c long cff_get_sid(cff_font * cff, const char *str) { card16 i; - if (!cff || !str) return -1; - - /* I search String INDEX first. */ + /*tex We search the string index first. */ if (cff && cff->string) { cff_index *idx = cff->string; for (i = 0; i < idx->count; i++) { @@ -1564,16 +1456,13 @@ long cff_get_sid(cff_font * cff, const char *str) return (i + CFF_STDSTR_MAX); } } - for (i = 0; i < CFF_STDSTR_MAX; i++) { if (!strcmp(str, cff_stdstr[i])) return i; } - return -1; } -@ @c void cff_update_string(cff_font * cff) { if (cff == NULL) @@ -1584,7 +1473,6 @@ void cff_update_string(cff_font * cff) cff->_string = NULL; } -@ @c s_SID cff_add_string(cff_font * cff, const char *str) { card16 idx; @@ -1621,7 +1509,6 @@ s_SID cff_add_string(cff_font * cff, const char *str) return (s_SID) (idx + CFF_STDSTR_MAX); } -@ @c void cff_dict_update(cff_dict * dict, cff_font * cff) { int i; @@ -1652,26 +1539,23 @@ void cff_dict_update(cff_dict * dict, cff_font * cff) } } -@ charsets -@c +/*tex The charsets. */ + long cff_read_charsets(cff_font * cff) { cff_charsets *charset; long offset, length; card16 count, i; - if (cff->topdict == NULL) normal_error("cff","top DICT not available"); - if (!cff_dict_known(cff->topdict, "charset")) { cff->flag |= CHARSETS_ISOADOBE; cff->charsets = NULL; return 0; } - offset = (long) cff_dict_get(cff->topdict, "charset", 0); - - if (offset == 0) { /* predefined */ + if (offset == 0) { + /*tex predefined */ cff->flag |= CHARSETS_ISOADOBE; cff->charsets = NULL; return 0; @@ -1684,170 +1568,158 @@ long cff_read_charsets(cff_font * cff) cff->charsets = NULL; return 0; } - cff->offset = (l_offset) offset; cff->charsets = charset = xcalloc(1, sizeof(cff_charsets)); charset->format = get_card8(cff); charset->num_entries = 0; - count = (card16) (cff->num_glyphs - 1); length = 1; - - /* Not sure. Not well documented. */ + /*tex Not well documented. */ switch (charset->format) { - case 0: - charset->num_entries = (card16) (cff->num_glyphs - 1); /* no .notdef */ - charset->data.glyphs = - xmalloc((unsigned) (charset->num_entries * sizeof(s_SID))); - length += (charset->num_entries) * 2; - for (i = 0; i < (charset->num_entries); i++) { - charset->data.glyphs[i] = get_card16(cff); - } - count = 0; - break; - case 1: - { - cff_range1 *ranges = NULL; - while (count > 0 && charset->num_entries < cff->num_glyphs) { - ranges = - xrealloc(ranges, - (unsigned) (((unsigned) charset->num_entries + - 1) * sizeof(cff_range1))); - ranges[charset->num_entries].first = get_card16(cff); - ranges[charset->num_entries].n_left = get_card8(cff); - count = (card16) (count - ranges[charset->num_entries].n_left + 1); /* no-overrap */ - charset->num_entries++; - charset->data.range1 = ranges; + case 0: + charset->num_entries = (card16) (cff->num_glyphs - 1); /* no .notdef */ + charset->data.glyphs = + xmalloc((unsigned) (charset->num_entries * sizeof(s_SID))); + length += (charset->num_entries) * 2; + for (i = 0; i < (charset->num_entries); i++) { + charset->data.glyphs[i] = get_card16(cff); } - length += (charset->num_entries) * 3; - } - break; - case 2: - { - cff_range2 *ranges = NULL; - while (count > 0 && charset->num_entries < cff->num_glyphs) { - ranges = - xrealloc(ranges, - (unsigned) (((unsigned) charset->num_entries + - 1) * sizeof(cff_range2))); - ranges[charset->num_entries].first = get_card16(cff); - ranges[charset->num_entries].n_left = get_card16(cff); - count = (card16) (count - (ranges[charset->num_entries].n_left + 1)); /* non-overrapping */ - charset->num_entries++; + count = 0; + break; + case 1: + { + cff_range1 *ranges = NULL; + while (count > 0 && charset->num_entries < cff->num_glyphs) { + ranges = + xrealloc(ranges, + (unsigned) (((unsigned) charset->num_entries + + 1) * sizeof(cff_range1))); + ranges[charset->num_entries].first = get_card16(cff); + ranges[charset->num_entries].n_left = get_card8(cff); + count = (card16) (count - ranges[charset->num_entries].n_left + 1); /* no-overrap */ + charset->num_entries++; + charset->data.range1 = ranges; + } + length += (charset->num_entries) * 3; } - charset->data.range2 = ranges; - length += (charset->num_entries) * 4; - } - break; - default: - xfree(charset); - normal_error("cff","unknown charset format"); - break; + break; + case 2: + { + cff_range2 *ranges = NULL; + while (count > 0 && charset->num_entries < cff->num_glyphs) { + ranges = + xrealloc(ranges, + (unsigned) (((unsigned) charset->num_entries + + 1) * sizeof(cff_range2))); + ranges[charset->num_entries].first = get_card16(cff); + ranges[charset->num_entries].n_left = get_card16(cff); + count = (card16) (count - (ranges[charset->num_entries].n_left + 1)); /* non-overrapping */ + charset->num_entries++; + } + charset->data.range2 = ranges; + length += (charset->num_entries) * 4; + } + break; + default: + xfree(charset); + normal_error("cff","unknown charset format"); + break; } - if (count > 0) { normal_warning("cff","charset data possibly broken (too many glyphs)"); } - return length; } -@ @c long cff_pack_charsets(cff_font * cff, card8 * dest, long destlen) { long len = 0; card16 i; cff_charsets *charset; - if (cff->flag & HAVE_STANDARD_CHARSETS || cff->charsets == NULL) return 0; - if (destlen < 1) normal_error("cff","buffer overflow (15)"); - charset = cff->charsets; - dest[len++] = charset->format; switch (charset->format) { - case 0: - if (destlen < len + (charset->num_entries) * 2) - normal_error("cff","buffer overflow (16)"); - for (i = 0; i < (charset->num_entries); i++) { - s_SID sid = (charset->data).glyphs[i]; /* or CID */ - dest[len++] = (card8) ((sid >> 8) & 0xff); - dest[len++] = (card8) (sid & 0xff); - } - break; - case 1: - { - if (destlen < len + (charset->num_entries) * 3) - normal_error("cff","buffer overflow (17)"); + case 0: + if (destlen < len + (charset->num_entries) * 2) + normal_error("cff","buffer overflow (16)"); for (i = 0; i < (charset->num_entries); i++) { - dest[len++] = (card8) (((charset->data).range1[i].first >> 8) & 0xff); - dest[len++] = (card8) ((charset->data).range1[i].first & 0xff); - dest[len++] = (card8) ((charset->data).range1[i].n_left); + s_SID sid = (charset->data).glyphs[i]; /* or CID */ + dest[len++] = (card8) ((sid >> 8) & 0xff); + dest[len++] = (card8) (sid & 0xff); } - } - break; - case 2: - { - if (destlen < len + (charset->num_entries) * 4) - normal_error("cff","buffer overflow (18)"); - for (i = 0; i < (charset->num_entries); i++) { - dest[len++] = (card8) (((charset->data).range2[i].first >> 8) & 0xff); - dest[len++] = (card8) ((charset->data).range2[i].first & 0xff); - dest[len++] = (card8) (((charset->data).range2[i].n_left >> 8) & 0xff); - dest[len++] = (card8) ((charset->data).range2[i].n_left & 0xff); + break; + case 1: + { + if (destlen < len + (charset->num_entries) * 3) + normal_error("cff","buffer overflow (17)"); + for (i = 0; i < (charset->num_entries); i++) { + dest[len++] = (card8) (((charset->data).range1[i].first >> 8) & 0xff); + dest[len++] = (card8) ((charset->data).range1[i].first & 0xff); + dest[len++] = (card8) ((charset->data).range1[i].n_left); + } } - } - break; - default: - normal_error("cff","unknown charset format"); - break; + break; + case 2: + { + if (destlen < len + (charset->num_entries) * 4) + normal_error("cff","buffer overflow (18)"); + for (i = 0; i < (charset->num_entries); i++) { + dest[len++] = (card8) (((charset->data).range2[i].first >> 8) & 0xff); + dest[len++] = (card8) ((charset->data).range2[i].first & 0xff); + dest[len++] = (card8) (((charset->data).range2[i].n_left >> 8) & 0xff); + dest[len++] = (card8) ((charset->data).range2[i].n_left & 0xff); + } + } + break; + default: + normal_error("cff","unknown charset format"); + break; } - return len; } +/*tex + Here we decode and encode Type 2 charstring. All local/global subroutine + calls in a given charstring is replace by the content of subroutine + charstrings. We do this because some PostScript RIP may have problems with + sparse subroutine array. Workaround for this is to re-order subroutine array + so that no gap appears in the subroutine array, or put dummy charstrings that + contains only `return' in the gap. However, re-ordering of subroutine is + rather difficult for Type 2 charstrings due to the bias which depends on the + total number of subroutines. Replacing callgsubr/callsubr calls with the + content of the corresponding subroutine charstring may be more efficient than + putting dummy subroutines in the case of subsetted font. Adobe distiller + seems doing same thing. -@* Type 2 Charstring support. - -Decode and encode Type 2 charstring + And also note that subroutine numbers within subroutines can depend on the + content of operand stack as follows: -All local/global subroutine calls in a given charstring is replace by the -content of subroutine charstrings. We do this because some PostScript RIP -may have problems with sparse subroutine array. Workaround for this is to -re-order subroutine array so that no gap appears in the subroutine array, -or put dummy charstrings that contains only `return' in the gap. However, -re-ordering of subroutine is rather difficult for Type 2 charstrings due -to the bias which depends on the total number of subroutines. Replacing -callgsubr/callsubr calls with the content of the corresponding subroutine -charstring may be more efficient than putting dummy subroutines in the -case of subsetted font. Adobe distiller seems doing same thing. + \startyping + \.{ ... l m callsubr << subr \#(m+bias): n add callsubr >> ...} + \stoptyping -And also note that subroutine numbers within subroutines can depend on the -content of operand stack as follows: + I've not implemented the `random' operator which generates a pseudo-random + number in the range (0, 1] and push them into argument stack. How + pseudo-random sequences are generated is not documented in the Type 2 + charstring spec. -\.{ ... l m callsubr << subr \#(m+bias): n add callsubr >> ...} - -I've not implemented the `random' operator which generates a pseudo-random -number in the range (0, 1] and push them into argument stack. -How pseudo-random sequences are generated is not documented in the Type 2 -charstring spec.. +*/ -@c -#define CS_TYPE2_DEBUG_STR "Type2 Charstring Parser" -#define CS_TYPE2_DEBUG 5 +#define CS_TYPE2_DEBUG_STR "Type2 Charstring Parser" +#define CS_TYPE2_DEBUG 5 -/* decoder/encoder status codes */ #define CS_BUFFER_CFF_ERROR -3 #define CS_STACK_CFF_ERROR -2 #define CS_PARSE_CFF_ERROR -1 -#define CS_PARSE_OK 0 -#define CS_PARSE_END 1 -#define CS_SUBR_RETURN 2 -#define CS_CHAR_END 3 +#define CS_PARSE_OK 0 +#define CS_PARSE_END 1 +#define CS_SUBR_RETURN 2 +#define CS_CHAR_END 3 static int status = CS_PARSE_CFF_ERROR; @@ -1855,54 +1727,57 @@ static int status = CS_PARSE_CFF_ERROR; #define SRC_NEED(a,b) {if ((a) < (b)) { status = CS_PARSE_CFF_ERROR ; return ; }} #define NEED(a,b) {if ((a) < (b)) { status = CS_STACK_CFF_ERROR ; return ; }} -/* hintmask and cntrmask need number of stem zones */ +/*tex The hintmask and cntrmask need the number of stem zones. */ + static int num_stems = 0; static int phase = 0; -/* subroutine nesting */ +/*tex Subroutine nesting. +*/ static int cs2_nest = 0; -/* advance width */ +/*tex The advance width. */ + static int have_width = 0; static double width = 0.0; -@ Standard Encoding Accented Characters: Optional four arguments for -endchar. See, CFF spec., p.35. This is obsolete feature and is no longer -supported. -@c -#if 0 -/* adx ady bchar achar endchar */ -static double seac[4] = { 0.0, 0.0, 0.0, 0.0 }; -#endif - -@ Operand stack and Transient array -@c +/*tex + + Standard Encoding Accented Characters: Optional four arguments for endchar. + See, CFF spec., p.35. This is obsolete feature and is no longer supported. + + \starttyping + static double seac[4] = { 0.0, 0.0, 0.0, 0.0 }; // gone + \stoptyping + +*/ + +/*tex Operand stack and Transient array */ + static int cs2_stack_top = 0; static double cs2_arg_stack[CS_ARG_STACK_MAX]; static double trn_array[CS_TRANS_ARRAY_MAX]; -@ Type 2 CharString encoding -@c +/*tex + + Type 2 CharString encoding, first the 1 byte operators: -/* - 1-byte CharString operators: - |cs_escape| is first byte of two-byte operator */ -/* RESERVED 0 */ -#define cs_hstem 1 -/* RESERVED 2 */ -#define cs_vstem 3 -#define cs_vmoveto 4 -#define cs_rlineto 5 -#define cs_hlineto 6 -#define cs_vlineto 7 -#define cs_rrcurveto 8 -/* |cs_closepath| 9 : TYPE1 */ +/* RESERVED 0 */ +#define cs_hstem 1 +/* RESERVED 2 */ +#define cs_vstem 3 +#define cs_vmoveto 4 +#define cs_rlineto 5 +#define cs_hlineto 6 +#define cs_vlineto 7 +#define cs_rrcurveto 8 +/* cs_closepath 9 */ #define cs_callsubr 10 #define cs_return 11 #define cs_escape 12 -/* |cs_hsbw| 13 : TYPE1 */ +/* cs_hsbw 13 */ #define cs_endchar 14 #define cs_setvsindex 15 #define cs_blend 16 @@ -1917,84 +1792,86 @@ static double trn_array[CS_TRANS_ARRAY_MAX]; #define cs_rlinecurve 25 #define cs_vvcurveto 26 #define cs_hhcurveto 27 -/* SHORTINT 28 : first byte of shortint*/ +/* SHORTINT 28 */ #define cs_callgsubr 29 #define cs_vhcurveto 30 #define cs_hvcurveto 31 -/* - 2-byte CharString operaotrs: - "dotsection" is obsoleted in Type 2 charstring. - */ - -#define cs_dotsection 0 -/* |cs_vstem3| 1 : TYPE1 */ -/* |cs_hstem3| 2 : TYPE1 */ -#define cs_and 3 -#define cs_or 4 -#define cs_not 5 -/* |cs_seac| 6 : TYPE1 */ -/* |cs_sbw| 7 : TYPE1 */ -/* RESERVED 8 */ -#define cs_abs 9 -#define cs_add 10 -#define cs_sub 11 -#define cs_div 12 -/* RESERVED 13 */ -#define cs_neg 14 -#define cs_eq 15 -/* |cs_callothersubr| 16 : TYPE1 */ -/* |cs_pop| 17 : TYPE1 */ -#define cs_drop 18 -/* RESERVED 19 */ -#define cs_put 20 -#define cs_get 21 -#define cs_ifelse 22 -#define cs_random 23 -#define cs_mul 24 -/* RESERVED 25 */ -#define cs_sqrt 26 -#define cs_dup 27 -#define cs_exch 28 -#define cs_index 29 -#define cs_roll 30 -/* |cs_setcurrentpoint| 31 : TYPE1 */ -/* RESERVED 32 */ -/* RESERVED 33 */ -#define cs_hflex 34 -#define cs_flex 35 -#define cs_hflex1 36 -#define cs_flex1 37 - -@ |clear_stack()| put all operands sotred in operand stack to dest. -@c +/*tex + + Next the two byte CharString operators: + +*/ + +#define cs_dotsection 0 +/* cs_vstem3 1 */ +/* cs_hstem3 2 */ +#define cs_and 3 +#define cs_or 4 +#define cs_not 5 +/* cs_seac 6 */ +/* cs_sbw 7 */ +/* RESERVED 8 */ +#define cs_abs 9 +#define cs_add 10 +#define cs_sub 11 +#define cs_div 12 +/* RESERVED 13 */ +#define cs_neg 14 +#define cs_eq 15 +/* cs_callothersubr 16 */ +/* cs_pop| 17 */ +#define cs_drop 18 +/* RESERVED 19 */ +#define cs_put 20 +#define cs_get 21 +#define cs_ifelse 22 +#define cs_random 23 +#define cs_mul 24 +/* RESERVED 25 */ +#define cs_sqrt 26 +#define cs_dup 27 +#define cs_exch 28 +#define cs_index 29 +#define cs_roll 30 +/* cs_setcurrentpoint 31 */ +/* RESERVED 32 */ +/* RESERVED 33 */ +#define cs_hflex 34 +#define cs_flex 35 +#define cs_hflex1 36 +#define cs_flex1 37 + +/*tex |clear_stack| put all operands sotred in operand stack to dest. */ + static void clear_stack(card8 ** dest, card8 * limit) { int i; - for (i = 0; i < cs2_stack_top; i++) { double value; long ivalue; value = cs2_arg_stack[i]; - /* Nearest integer value */ + /*tex The nearest integer value. */ ivalue = (long) floor(value + 0.5); if (value >= 0x8000L || value <= (-0x8000L - 1)) { - /* + /*tex This number cannot be represented as a single operand. We must - use `a b mul ...' or `a c div' to represent large values. + use |a b mul ...| or |a c div| to represent large values. */ normal_error("cff","argument value too large (this is bug)"); } else if (fabs(value - (double) ivalue) > 3.0e-5) { - /* 16.16-bit signed fixed value */ + /*tex A 16.16-bit signed fixed value */ DST_NEED(limit, *dest + 5); *(*dest)++ = 255; - ivalue = (long) floor(value); /* mantissa */ + /*tex The mantissa. */ + ivalue = (long) floor(value); *(*dest)++ = (card8) ((ivalue >> 8) & 0xff); *(*dest)++ = (card8) (ivalue & 0xff); - ivalue = (long) ((value - (double) ivalue) * 0x10000l); /* fraction */ + /*tex The fraction. */ + ivalue = (long) ((value - (double) ivalue) * 0x10000l); *(*dest)++ = (card8) ((ivalue >> 8) & 0xff); *(*dest)++ = (card8) (ivalue & 0xff); - /* Everything else are integers. */ + /*tex Everything else is integer. */ } else if (ivalue >= -107 && ivalue <= 107) { DST_NEED(limit, *dest + 1); *(*dest)++ = (card8) (ivalue + 139); @@ -2009,31 +1886,30 @@ static void clear_stack(card8 ** dest, card8 * limit) *(*dest)++ = (card8) ((ivalue >> 8) & 0xff); *(*dest)++ = (card8) (ivalue & 0xff); } else if (ivalue >= -32768 && ivalue <= 32767) { - /* shortint */ + /*tex A shortint. */ DST_NEED(limit, *dest + 3); *(*dest)++ = 28; *(*dest)++ = (card8) ((ivalue >> 8) & 0xff); *(*dest)++ = (card8) ((ivalue) & 0xff); - } else { /* Shouldn't come here */ + } else { normal_error("cff","unexpected error"); } } - cs2_stack_top = 0; /* clear stack */ + /*tex Clear the stack. */ + cs2_stack_top = 0; return; } -@ Single byte operators: Path construction, Operator for finishing a -path, Hint operators. Phases: +/*tex + Single byte operators: Path construction, Operator for finishing a path, Hint + operators. Phases: -\item 0: inital state -\item 1: hint declaration, first stack-clearing operator appeared -\item 2: in path construction + \starttabulate + \NC \type{0} \NC inital state \NC \NR + \NC \type{1} \NC hint declaration, first stack-clearing operator appeared \NC \NR + \NC \type{2} \NC in path construction \NC \NR + \stoptabulate -@c -/* -static int vsindex = 0; -static int blends = 0; -static int regions = 5; */ static void do_operator1(card8 ** dest, card8 * limit, card8 ** data, card8 * endptr) @@ -2043,351 +1919,347 @@ static void do_operator1(card8 ** dest, card8 * limit, card8 ** data, card8 * en *data += 1; switch (op) { - case cs_hstemhm: - case cs_vstemhm: - /* charstring may have hintmask if above operator have seen */ - case cs_hstem: - case cs_vstem: - if (phase == 0 && (cs2_stack_top % 2)) { - have_width = 1; - width = cs2_arg_stack[0]; - } - num_stems += cs2_stack_top / 2; - clear_stack(dest, limit); - DST_NEED(limit, *dest + 1); - *(*dest)++ = op; - phase = 1; - break; - case cs_hintmask: - case cs_cntrmask: - if (phase < 2) { + case cs_hstemhm: + case cs_vstemhm: + /*tex A charstring may have a hintmask if the above operator has been seen. */ + case cs_hstem: + case cs_vstem: if (phase == 0 && (cs2_stack_top % 2)) { have_width = 1; width = cs2_arg_stack[0]; } num_stems += cs2_stack_top / 2; - } - clear_stack(dest, limit); - DST_NEED(limit, *dest + 1); - *(*dest)++ = op; - if (num_stems > 0) { - int masklen = (num_stems + 7) / 8; - DST_NEED(limit, *dest + masklen); - SRC_NEED(endptr, *data + masklen); - memmove(*dest, *data, (size_t) masklen); - *data += masklen; - *dest += masklen; - } - phase = 2; - break; - case cs_rmoveto: - if (phase == 0 && (cs2_stack_top % 2)) { - have_width = 1; - width = cs2_arg_stack[0]; - } - clear_stack(dest, limit); - DST_NEED(limit, *dest + 1); - *(*dest)++ = op; - phase = 2; - break; - case cs_hmoveto: - case cs_vmoveto: - if (phase == 0 && (cs2_stack_top % 2) == 0) { - have_width = 1; - width = cs2_arg_stack[0]; - } - clear_stack(dest, limit); - DST_NEED(limit, *dest + 1); - *(*dest)++ = op; - phase = 2; - break; - case cs_endchar: - if (cs2_stack_top == 1) { - have_width = 1; - width = cs2_arg_stack[0]; clear_stack(dest, limit); - } else if (cs2_stack_top == 4 || cs2_stack_top == 5) { - normal_warning("cff","'seac' character deprecated in type 2 charstring"); + DST_NEED(limit, *dest + 1); + *(*dest)++ = op; + phase = 1; + break; + case cs_hintmask: + case cs_cntrmask: + if (phase < 2) { + if (phase == 0 && (cs2_stack_top % 2)) { + have_width = 1; + width = cs2_arg_stack[0]; + } + num_stems += cs2_stack_top / 2; + } + clear_stack(dest, limit); + DST_NEED(limit, *dest + 1); + *(*dest)++ = op; + if (num_stems > 0) { + int masklen = (num_stems + 7) / 8; + DST_NEED(limit, *dest + masklen); + SRC_NEED(endptr, *data + masklen); + memmove(*dest, *data, (size_t) masklen); + *data += masklen; + *dest += masklen; + } + phase = 2; + break; + case cs_rmoveto: + if (phase == 0 && (cs2_stack_top % 2)) { + have_width = 1; + width = cs2_arg_stack[0]; + } + clear_stack(dest, limit); + DST_NEED(limit, *dest + 1); + *(*dest)++ = op; + phase = 2; + break; + case cs_hmoveto: + case cs_vmoveto: + if (phase == 0 && (cs2_stack_top % 2) == 0) { + have_width = 1; + width = cs2_arg_stack[0]; + } + clear_stack(dest, limit); + DST_NEED(limit, *dest + 1); + *(*dest)++ = op; + phase = 2; + break; + case cs_endchar: + if (cs2_stack_top == 1) { + have_width = 1; + width = cs2_arg_stack[0]; + clear_stack(dest, limit); + } else if (cs2_stack_top == 4 || cs2_stack_top == 5) { + normal_warning("cff","'seac' character deprecated in type 2 charstring"); + status = CS_PARSE_CFF_ERROR; + return; + } else if (cs2_stack_top > 0) { + normal_warning("cff","operand stack not empty"); + } + DST_NEED(limit, *dest + 1); + *(*dest)++ = op; + status = CS_CHAR_END; + break; + /*tex The above operators are candidate for first stack clearing operator. */ + case cs_setvsindex: + /* + vsindex = cs2_arg_stack[cs2_stack_top-1]; + cs2_stack_top -= 1; + */ + normal_warning("cff2","unsupported setvindex operator"); status = CS_PARSE_CFF_ERROR; - return; - } else if (cs2_stack_top > 0) { - normal_warning("cff","operand stack not empty"); - } - DST_NEED(limit, *dest + 1); - *(*dest)++ = op; - status = CS_CHAR_END; - break; - /* above operators are candidate for first stack-clearing operator */ - case cs_setvsindex: - /* - vsindex = cs2_arg_stack[cs2_stack_top-1]; - cs2_stack_top -= 1; - */ - normal_warning("cff2","unsupported setvindex operator"); - status = CS_PARSE_CFF_ERROR; - break; - case cs_blend: - /* - blends = cs2_arg_stack[cs2_stack_top-1]; - cs2_stack_top -= 1; - cs2_stack_top -= blends * regions ; - */ - normal_warning("cff2","unsupported blend operator"); - status = CS_PARSE_CFF_ERROR; - break; - case cs_rlineto: - case cs_hlineto: - case cs_vlineto: - case cs_rrcurveto: - case cs_rcurveline: - case cs_rlinecurve: - case cs_vvcurveto: - case cs_hhcurveto: - case cs_vhcurveto: - case cs_hvcurveto: - if (phase < 2) { - normal_warning("cff","broken type 2 charstring"); + break; + case cs_blend: + /* + blends = cs2_arg_stack[cs2_stack_top-1]; + cs2_stack_top -= 1; + cs2_stack_top -= blends * regions ; + */ + normal_warning("cff2","unsupported blend operator"); status = CS_PARSE_CFF_ERROR; - return; - } - clear_stack(dest, limit); - DST_NEED(limit, *dest + 1); - *(*dest)++ = op; - break; - /* all operotors above are stack-clearing operator */ - /* no output */ - case cs_return: - case cs_callgsubr: - case cs_callsubr: - normal_error("cff","unexpected call(g)subr/return"); - break; - default: - /* no-op ? */ - formatted_warning("cff","%s: unknown charstring operator: 0x%02x", CS_TYPE2_DEBUG_STR, op); - status = CS_PARSE_CFF_ERROR; - break; + break; + case cs_rlineto: + case cs_hlineto: + case cs_vlineto: + case cs_rrcurveto: + case cs_rcurveline: + case cs_rlinecurve: + case cs_vvcurveto: + case cs_hhcurveto: + case cs_vhcurveto: + case cs_hvcurveto: + if (phase < 2) { + normal_warning("cff","broken type 2 charstring"); + status = CS_PARSE_CFF_ERROR; + return; + } + clear_stack(dest, limit); + DST_NEED(limit, *dest + 1); + *(*dest)++ = op; + break; + /*tex All the operotors above are stack clearing. */ + case cs_return: + normal_error("cff","unexpected return"); + case cs_callgsubr: + normal_error("cff","unexpected callgsubr"); + case cs_callsubr: + normal_error("cff","unexpected callsubr"); + break; + default: + formatted_warning("cff","%s: unknown charstring operator: 0x%02x", CS_TYPE2_DEBUG_STR, op); + status = CS_PARSE_CFF_ERROR; + break; } return; } -@ Double byte operators: Flex, arithmetic, conditional, and storage operators. -The following operators are not supported: random: How random ? +/*tex + + Double byte operators: Flex, arithmetic, conditional, and storage operators. + The following operators are not supported: random but How random ? + +*/ -@c static void do_operator2(card8 ** dest, card8 * limit, card8 ** data, card8 * endptr) { card8 op; - *data += 1; - SRC_NEED(endptr, *data + 1); - op = **data; *data += 1; - switch (op) { - case cs_dotsection: /* deprecated */ - normal_warning("cff","Operator 'dotsection' deprecated in type 2 charstring"); - status = CS_PARSE_CFF_ERROR; - return; - break; - case cs_hflex: - case cs_flex: - case cs_hflex1: - case cs_flex1: - if (phase < 2) { - formatted_warning("cff","%s: broken type 2 charstring", CS_TYPE2_DEBUG_STR); + case cs_dotsection: + normal_warning("cff","Operator 'dotsection' deprecated in type 2 charstring"); status = CS_PARSE_CFF_ERROR; return; - } - clear_stack(dest, limit); - DST_NEED(limit, *dest + 2); - *(*dest)++ = cs_escape; - *(*dest)++ = op; - break; - /* all operator above are stack-clearing */ - /* no output */ - case cs_and: - NEED(cs2_stack_top, 2); - cs2_stack_top--; - if (cs2_arg_stack[cs2_stack_top] && cs2_arg_stack[cs2_stack_top - 1]) { - cs2_arg_stack[cs2_stack_top - 1] = 1.0; - } else { - cs2_arg_stack[cs2_stack_top - 1] = 0.0; - } - break; - case cs_or: - NEED(cs2_stack_top, 2); - cs2_stack_top--; - if (cs2_arg_stack[cs2_stack_top] || cs2_arg_stack[cs2_stack_top - 1]) { - cs2_arg_stack[cs2_stack_top - 1] = 1.0; - } else { - cs2_arg_stack[cs2_stack_top - 1] = 0.0; - } - break; - case cs_not: - NEED(cs2_stack_top, 1); - if (cs2_arg_stack[cs2_stack_top - 1]) { - cs2_arg_stack[cs2_stack_top - 1] = 0.0; - } else { - cs2_arg_stack[cs2_stack_top - 1] = 1.0; - } - break; - case cs_abs: - NEED(cs2_stack_top, 1); - cs2_arg_stack[cs2_stack_top - 1] = - fabs(cs2_arg_stack[cs2_stack_top - 1]); - break; - case cs_add: - NEED(cs2_stack_top, 2); - cs2_arg_stack[cs2_stack_top - 2] += cs2_arg_stack[cs2_stack_top - 1]; - cs2_stack_top--; - break; - case cs_sub: - NEED(cs2_stack_top, 2); - cs2_arg_stack[cs2_stack_top - 2] -= cs2_arg_stack[cs2_stack_top - 1]; - cs2_stack_top--; - break; - case cs_div: /* doesn't check overflow */ - NEED(cs2_stack_top, 2); - cs2_arg_stack[cs2_stack_top - 2] /= cs2_arg_stack[cs2_stack_top - 1]; - cs2_stack_top--; - break; - case cs_neg: - NEED(cs2_stack_top, 1); - cs2_arg_stack[cs2_stack_top - 1] *= -1.0; - break; - case cs_eq: - NEED(cs2_stack_top, 2); - cs2_stack_top--; - if (cs2_arg_stack[cs2_stack_top] == cs2_arg_stack[cs2_stack_top - 1]) { - cs2_arg_stack[cs2_stack_top - 1] = 1.0; - } else { - cs2_arg_stack[cs2_stack_top - 1] = 0.0; - } - break; - case cs_drop: - NEED(cs2_stack_top, 1); - cs2_stack_top--; - break; - case cs_put: - NEED(cs2_stack_top, 2); - { - int idx = (int) cs2_arg_stack[--cs2_stack_top]; - NEED(CS_TRANS_ARRAY_MAX, idx); - trn_array[idx] = cs2_arg_stack[--cs2_stack_top]; - } - break; - case cs_get: - NEED(cs2_stack_top, 1); - { - int idx = (int) cs2_arg_stack[cs2_stack_top - 1]; - NEED(CS_TRANS_ARRAY_MAX, idx); - cs2_arg_stack[cs2_stack_top - 1] = trn_array[idx]; - } - break; - case cs_ifelse: - NEED(cs2_stack_top, 4); - cs2_stack_top -= 3; - if (cs2_arg_stack[cs2_stack_top + 1] > cs2_arg_stack[cs2_stack_top + 2]) { - cs2_arg_stack[cs2_stack_top - 1] = cs2_arg_stack[cs2_stack_top]; - } - break; - case cs_mul: - NEED(cs2_stack_top, 2); - cs2_arg_stack[cs2_stack_top - 2] = - cs2_arg_stack[cs2_stack_top - 2] * cs2_arg_stack[cs2_stack_top - 1]; - cs2_stack_top--; - break; - case cs_sqrt: - NEED(cs2_stack_top, 1); - cs2_arg_stack[cs2_stack_top - 1] = - sqrt(cs2_arg_stack[cs2_stack_top - 1]); - break; - case cs_dup: - NEED(cs2_stack_top, 1); - NEED(CS_ARG_STACK_MAX, cs2_stack_top + 1); - cs2_arg_stack[cs2_stack_top] = cs2_arg_stack[cs2_stack_top - 1]; - cs2_stack_top++; - break; - case cs_exch: - NEED(cs2_stack_top, 2); - { - double save = cs2_arg_stack[cs2_stack_top - 2]; - cs2_arg_stack[cs2_stack_top - 2] = cs2_arg_stack[cs2_stack_top - 1]; - cs2_arg_stack[cs2_stack_top - 1] = save; - } - break; - case cs_index: - NEED(cs2_stack_top, 2); /* need two arguments at least */ - { - int idx = (int) cs2_arg_stack[cs2_stack_top - 1]; - if (idx < 0) { - cs2_arg_stack[cs2_stack_top - 1] = - cs2_arg_stack[cs2_stack_top - 2]; + break; + case cs_hflex: + case cs_flex: + case cs_hflex1: + case cs_flex1: + if (phase < 2) { + formatted_warning("cff","%s: broken type 2 charstring", CS_TYPE2_DEBUG_STR); + status = CS_PARSE_CFF_ERROR; + return; + } + clear_stack(dest, limit); + DST_NEED(limit, *dest + 2); + *(*dest)++ = cs_escape; + *(*dest)++ = op; + break; + /*tex All operators above are stack clearing. */ + case cs_and: + NEED(cs2_stack_top, 2); + cs2_stack_top--; + if (cs2_arg_stack[cs2_stack_top] && cs2_arg_stack[cs2_stack_top - 1]) { + cs2_arg_stack[cs2_stack_top - 1] = 1.0; } else { - NEED(cs2_stack_top, idx + 2); - cs2_arg_stack[cs2_stack_top - 1] = - cs2_arg_stack[cs2_stack_top - idx - 2]; + cs2_arg_stack[cs2_stack_top - 1] = 0.0; } - } - break; - case cs_roll: - NEED(cs2_stack_top, 2); - { - int N, J; - J = (int) cs2_arg_stack[--cs2_stack_top]; - N = (int) cs2_arg_stack[--cs2_stack_top]; - NEED(cs2_stack_top, N); - if (J > 0) { - J = J % N; - while (J-- > 0) { - double save = cs2_arg_stack[cs2_stack_top - 1]; - int i = cs2_stack_top - 1; - while (i > cs2_stack_top - N) { - cs2_arg_stack[i] = cs2_arg_stack[i - 1]; - i--; - } - cs2_arg_stack[i] = save; - } + break; + case cs_or: + NEED(cs2_stack_top, 2); + cs2_stack_top--; + if (cs2_arg_stack[cs2_stack_top] || cs2_arg_stack[cs2_stack_top - 1]) { + cs2_arg_stack[cs2_stack_top - 1] = 1.0; + } else { + cs2_arg_stack[cs2_stack_top - 1] = 0.0; + } + break; + case cs_not: + NEED(cs2_stack_top, 1); + if (cs2_arg_stack[cs2_stack_top - 1]) { + cs2_arg_stack[cs2_stack_top - 1] = 0.0; + } else { + cs2_arg_stack[cs2_stack_top - 1] = 1.0; + } + break; + case cs_abs: + NEED(cs2_stack_top, 1); + cs2_arg_stack[cs2_stack_top - 1] = + fabs(cs2_arg_stack[cs2_stack_top - 1]); + break; + case cs_add: + NEED(cs2_stack_top, 2); + cs2_arg_stack[cs2_stack_top - 2] += cs2_arg_stack[cs2_stack_top - 1]; + cs2_stack_top--; + break; + case cs_sub: + NEED(cs2_stack_top, 2); + cs2_arg_stack[cs2_stack_top - 2] -= cs2_arg_stack[cs2_stack_top - 1]; + cs2_stack_top--; + break; + case cs_div: + NEED(cs2_stack_top, 2); + cs2_arg_stack[cs2_stack_top - 2] /= cs2_arg_stack[cs2_stack_top - 1]; + cs2_stack_top--; + break; + case cs_neg: + NEED(cs2_stack_top, 1); + cs2_arg_stack[cs2_stack_top - 1] *= -1.0; + break; + case cs_eq: + NEED(cs2_stack_top, 2); + cs2_stack_top--; + if (cs2_arg_stack[cs2_stack_top] == cs2_arg_stack[cs2_stack_top - 1]) { + cs2_arg_stack[cs2_stack_top - 1] = 1.0; } else { - J = (-J) % N; - while (J-- > 0) { - double save = cs2_arg_stack[cs2_stack_top - N]; - int i = cs2_stack_top - N; - while (i < cs2_stack_top - 1) { - cs2_arg_stack[i] = cs2_arg_stack[i + 1]; - i++; + cs2_arg_stack[cs2_stack_top - 1] = 0.0; + } + break; + case cs_drop: + NEED(cs2_stack_top, 1); + cs2_stack_top--; + break; + case cs_put: + NEED(cs2_stack_top, 2); + { + int idx = (int) cs2_arg_stack[--cs2_stack_top]; + NEED(CS_TRANS_ARRAY_MAX, idx); + trn_array[idx] = cs2_arg_stack[--cs2_stack_top]; + } + break; + case cs_get: + NEED(cs2_stack_top, 1); + { + int idx = (int) cs2_arg_stack[cs2_stack_top - 1]; + NEED(CS_TRANS_ARRAY_MAX, idx); + cs2_arg_stack[cs2_stack_top - 1] = trn_array[idx]; + } + break; + case cs_ifelse: + NEED(cs2_stack_top, 4); + cs2_stack_top -= 3; + if (cs2_arg_stack[cs2_stack_top + 1] > cs2_arg_stack[cs2_stack_top + 2]) { + cs2_arg_stack[cs2_stack_top - 1] = cs2_arg_stack[cs2_stack_top]; + } + break; + case cs_mul: + NEED(cs2_stack_top, 2); + cs2_arg_stack[cs2_stack_top - 2] = + cs2_arg_stack[cs2_stack_top - 2] * cs2_arg_stack[cs2_stack_top - 1]; + cs2_stack_top--; + break; + case cs_sqrt: + NEED(cs2_stack_top, 1); + cs2_arg_stack[cs2_stack_top - 1] = + sqrt(cs2_arg_stack[cs2_stack_top - 1]); + break; + case cs_dup: + NEED(cs2_stack_top, 1); + NEED(CS_ARG_STACK_MAX, cs2_stack_top + 1); + cs2_arg_stack[cs2_stack_top] = cs2_arg_stack[cs2_stack_top - 1]; + cs2_stack_top++; + break; + case cs_exch: + NEED(cs2_stack_top, 2); + { + double save = cs2_arg_stack[cs2_stack_top - 2]; + cs2_arg_stack[cs2_stack_top - 2] = cs2_arg_stack[cs2_stack_top - 1]; + cs2_arg_stack[cs2_stack_top - 1] = save; + } + break; + case cs_index: + NEED(cs2_stack_top, 2); + { + int idx = (int) cs2_arg_stack[cs2_stack_top - 1]; + if (idx < 0) { + cs2_arg_stack[cs2_stack_top - 1] = + cs2_arg_stack[cs2_stack_top - 2]; + } else { + NEED(cs2_stack_top, idx + 2); + cs2_arg_stack[cs2_stack_top - 1] = + cs2_arg_stack[cs2_stack_top - idx - 2]; + } + } + break; + case cs_roll: + NEED(cs2_stack_top, 2); + { + int N, J; + J = (int) cs2_arg_stack[--cs2_stack_top]; + N = (int) cs2_arg_stack[--cs2_stack_top]; + NEED(cs2_stack_top, N); + if (J > 0) { + J = J % N; + while (J-- > 0) { + double save = cs2_arg_stack[cs2_stack_top - 1]; + int i = cs2_stack_top - 1; + while (i > cs2_stack_top - N) { + cs2_arg_stack[i] = cs2_arg_stack[i - 1]; + i--; + } + cs2_arg_stack[i] = save; + } + } else { + J = (-J) % N; + while (J-- > 0) { + double save = cs2_arg_stack[cs2_stack_top - N]; + int i = cs2_stack_top - N; + while (i < cs2_stack_top - 1) { + cs2_arg_stack[i] = cs2_arg_stack[i + 1]; + i++; + } + cs2_arg_stack[i] = save; } - cs2_arg_stack[i] = save; } } - } - break; - case cs_random: - formatted_warning("cff","%s: Charstring operator 'random' found.", CS_TYPE2_DEBUG_STR); - NEED(CS_ARG_STACK_MAX, cs2_stack_top + 1); - cs2_arg_stack[cs2_stack_top++] = 1.0; - break; - default: - /* no-op ? */ - formatted_warning("cff","%s: unknown charstring operator: 0x0c%02x", CS_TYPE2_DEBUG_STR, op); - status = CS_PARSE_CFF_ERROR; - break; + break; + case cs_random: + formatted_warning("cff","%s: Charstring operator 'random' found.", CS_TYPE2_DEBUG_STR); + NEED(CS_ARG_STACK_MAX, cs2_stack_top + 1); + cs2_arg_stack[cs2_stack_top++] = 1.0; + break; + default: + formatted_warning("cff","%s: unknown charstring operator: 0x0c%02x", CS_TYPE2_DEBUG_STR, op); + status = CS_PARSE_CFF_ERROR; + break; } return; } -@ integer: exactly the same as the DICT encoding (except 29) -@c +/*tex integer: exactly the same as the DICT encoding (except 29) */ + static void cs2_get_integer(card8 ** data, card8 * endptr) { long result = 0; card8 b0 = **data, b1, b2; - *data += 1; - - if (b0 == 28) { /* shortint */ + if (b0 == 28) { + /*tex shortint */ SRC_NEED(endptr, *data + 2); b1 = **data; b2 = *(*data + 1); @@ -2395,9 +2267,11 @@ static void cs2_get_integer(card8 ** data, card8 * endptr) if (result > 0x7fff) result -= 0x10000L; *data += 2; - } else if (b0 >= 32 && b0 <= 246) { /* int (1) */ + } else if (b0 >= 32 && b0 <= 246) { + /*tex int (1) */ result = b0 - 139; - } else if (b0 >= 247 && b0 <= 250) { /* int (2) */ + } else if (b0 >= 247 && b0 <= 250) { + /*tex int (2) */ SRC_NEED(endptr, *data + 1); b1 = **data; result = (b0 - 247) * 256 + b1 + 108; @@ -2416,48 +2290,45 @@ static void cs2_get_integer(card8 ** data, card8 * endptr) return; } -@ Signed 16.16-bits fixed number for Type 2 charstring encoding -@c +/*tex Signed 16.16-bits fixed number for Type 2 charstring encoding. */ + static void get_fixed(card8 ** data, card8 * endptr) { long ivalue; double rvalue; - *data += 1; - SRC_NEED(endptr, *data + 4); - ivalue = *(*data) * 0x100 + *(*data + 1); rvalue = (double) ((ivalue > 0x7fffL) ? (ivalue - 0x10000L) : ivalue); ivalue = *(*data + 2) * 0x100 + *(*data + 3); rvalue += ((double) ivalue) / 0x10000L; - NEED(CS_ARG_STACK_MAX, cs2_stack_top + 1); cs2_arg_stack[cs2_stack_top++] = rvalue; *data += 4; - return; } -@ Subroutines: the bias for subroutine number is introduced in type 2 +/*tex + +Subroutines: the bias for subroutine number is introduced in type 2 charstrings. -\item subr: set to a pointer to the subroutine charstring. -\item len: set to the length of subroutine charstring. -\item |subr_idx|: CFF INDEX data that contains subroutines. -\item id: biased subroutine number. +\starttabulate +\NC \type {subr} \NC set to a pointer to the subroutine charstring \NC \NR +\NC \type {len} \NC set to the length of subroutine charstring \NC \NR +\NC \type {subr_idx} \NC CFF INDEX data that contains subroutines \NC \NR +\NC \type {id} \NC biased subroutine number \NC \NR +\stoptabulate + +*/ -@c static void get_subr(card8 ** subr, long *len, cff_index * subr_idx, long id) { card16 count; - if (subr_idx == NULL) formatted_error("cff","%s: subroutine called but no subroutine found",CS_TYPE2_DEBUG_STR); - count = subr_idx->count; - - /* Adding bias number */ + /*tex addi the bias number */ if (count < 1240) { id += 107; } else if (count < 33900) { @@ -2465,36 +2336,33 @@ static void get_subr(card8 ** subr, long *len, cff_index * subr_idx, long id) } else { id += 32768; } - if (id > count) formatted_error("cff","%s: invalid subroutine index: %ld (max=%u)", CS_TYPE2_DEBUG_STR, id, count); - *len = (long) ((subr_idx->offset)[id + 1] - (subr_idx->offset)[id]); *subr = subr_idx->data + (subr_idx->offset)[id] - 1; - return; } -@ The Type 2 interpretation of a number encoded in five-bytes (those with -an initial byte value of 255) differs from how it is interpreted in the -Type 1 format. +/*tex -@c -static void do_charstring(card8 ** dest, card8 * limit, - card8 ** data, card8 * endptr, - cff_index * gsubr_idx, cff_index * subr_idx, int cff2) + The Type 2 interpretation of a number encoded in five-bytes (those with an + initial byte value of 255) differs from how it is interpreted in the Type 1 + format. + +*/ + +static void do_charstring(card8 ** dest, card8 * limit, card8 ** data, card8 * endptr, + cff_index * gsubr_idx, cff_index * subr_idx, int cff2) { card8 b0 = 0, *subr; long len; - if (cs2_nest > CS_SUBR_NEST_MAX) formatted_error("cff","%s: subroutine nested too deeply", CS_TYPE2_DEBUG_STR); - cs2_nest++; - while (*data < endptr && status == CS_PARSE_OK) { b0 = **data; - if (b0 == 255) { /* 16-bit.16-bit fixed signed number */ + if (b0 == 255) { + /*tex A 16-bit.16-bit fixed signed number. */ get_fixed(data, endptr); } else if (b0 == cs_return) { status = CS_SUBR_RETURN; @@ -2503,8 +2371,7 @@ static void do_charstring(card8 ** dest, card8 * limit, status = CS_STACK_CFF_ERROR; } else { cs2_stack_top--; - get_subr(&subr, &len, gsubr_idx, - (long) cs2_arg_stack[cs2_stack_top]); + get_subr(&subr, &len, gsubr_idx, (long) cs2_arg_stack[cs2_stack_top]); if (*dest + len > limit) formatted_error("cff","%s: possible buffer overflow (1)", CS_TYPE2_DEBUG_STR); do_charstring(dest, limit, &subr, subr + len, gsubr_idx, subr_idx, cff2); @@ -2515,8 +2382,7 @@ static void do_charstring(card8 ** dest, card8 * limit, status = CS_STACK_CFF_ERROR; } else { cs2_stack_top--; - get_subr(&subr, &len, subr_idx, - (long) cs2_arg_stack[cs2_stack_top]); + get_subr(&subr, &len, subr_idx, (long) cs2_arg_stack[cs2_stack_top]); if (limit < *dest + len) formatted_error("cff","%s: possible buffer overflow (2)", CS_TYPE2_DEBUG_STR); do_charstring(dest, limit, &subr, subr + len, gsubr_idx, subr_idx, cff2); @@ -2524,34 +2390,29 @@ static void do_charstring(card8 ** dest, card8 * limit, } } else if (b0 == cs_escape) { do_operator2(dest, limit, data, endptr); - } else if (b0 < 32 && b0 != 28) { /* 19, 20 need mask */ + } else if (b0 < 32 && b0 != 28) { do_operator1(dest, limit, data, endptr); - } else if ((b0 <= 22 && b0 >= 27) || b0 == 31) { /* reserved */ - status = CS_PARSE_CFF_ERROR; /* not an error ? */ - } else { /* integer */ + } else if ((b0 <= 22 && b0 >= 27) || b0 == 31) { + status = CS_PARSE_CFF_ERROR; + } else { cs2_get_integer(data, endptr); } } - if (cff2) { DST_NEED(limit, *dest + 1); ++endptr; *(*dest)++ = cs_endchar; - /* no return and endchar */ } else if (status == CS_SUBR_RETURN) { status = CS_PARSE_OK; } else if (status == CS_CHAR_END && *data < endptr) { formatted_warning("cff","%s: garbage after endchar", CS_TYPE2_DEBUG_STR); - } else if (status < CS_PARSE_OK) { /* error */ + } else if (status < CS_PARSE_OK) { formatted_error("cff","%s: parsing charstring failed: (status=%d, stack=%d)", CS_TYPE2_DEBUG_STR, status, cs2_stack_top); } - cs2_nest--; - return; } -@ @c static void cs_parse_init(void) { status = CS_PARSE_OK; @@ -2561,11 +2422,10 @@ static void cs_parse_init(void) cs2_stack_top = 0; } -@ Not just copying... -@c -static long cs_copy_charstring(card8 * dst, long dstlen, card8 * src, long srclen, - cff_index * gsubr, cff_index * subr, double default_width, - double nominal_width, cs_ginfo * ginfo, int cff2) +/*tex Not just copying \unknown */ + +static long cs_copy_charstring(card8 * dst, long dstlen, card8 * src, long srclen, cff_index * gsubr, + cff_index * subr, double default_width, double nominal_width, cs_ginfo * ginfo, int cff2) { card8 *save = dst; @@ -2589,195 +2449,183 @@ static long cs_copy_charstring(card8 * dst, long dstlen, card8 * src, long srcle return (long) (dst - save); } -@ CID-Keyed font specific -@c +/*tex CID-Keyed font specific. */ + long cff_read_fdselect(cff_font * cff) { cff_fdselect *fdsel; long offset, length; card16 i; - if (cff->topdict == NULL) normal_error("cff","top DICT not available"); - if (!(cff->flag & FONTTYPE_CIDFONT)) return 0; - offset = (long) cff_dict_get(cff->topdict, "FDSelect", 0); cff->offset = (l_offset) offset; cff->fdselect = fdsel = xcalloc(1, sizeof(cff_fdselect)); fdsel->format = get_card8(cff); - length = 1; - switch (fdsel->format) { - case 0: - fdsel->num_entries = cff->num_glyphs; - (fdsel->data).fds = xmalloc(fdsel->num_entries * sizeof(card8)); - for (i = 0; i < (fdsel->num_entries); i++) { - (fdsel->data).fds[i] = get_card8(cff); - } - length += fdsel->num_entries; - break; - case 3: - { - cff_range3 *ranges; - fdsel->num_entries = get_card16(cff); - fdsel->data.ranges = ranges = - xcalloc(fdsel->num_entries, sizeof(cff_range3)); + case 0: + fdsel->num_entries = cff->num_glyphs; + (fdsel->data).fds = xmalloc(fdsel->num_entries * sizeof(card8)); for (i = 0; i < (fdsel->num_entries); i++) { - ranges[i].first = get_card16(cff); - ranges[i].fd = get_card8(cff); + (fdsel->data).fds[i] = get_card8(cff); } - if (ranges[0].first != 0) - normal_error("cff","range not starting with 0"); - if (cff->num_glyphs != get_card16(cff)) - normal_error("cff","sentinel value mismatched with number of glyphs"); - length += (fdsel->num_entries) * 3 + 4; - } - break; - default: - xfree(fdsel); - normal_error("cff","unknown FDSelect format"); - break; + length += fdsel->num_entries; + break; + case 3: + { + cff_range3 *ranges; + fdsel->num_entries = get_card16(cff); + fdsel->data.ranges = ranges = + xcalloc(fdsel->num_entries, sizeof(cff_range3)); + for (i = 0; i < (fdsel->num_entries); i++) { + ranges[i].first = get_card16(cff); + ranges[i].fd = get_card8(cff); + } + if (ranges[0].first != 0) + normal_error("cff","range not starting with 0"); + if (cff->num_glyphs != get_card16(cff)) + normal_error("cff","sentinel value mismatched with number of glyphs"); + length += (fdsel->num_entries) * 3 + 4; + } + break; + default: + xfree(fdsel); + normal_error("cff","unknown FDSelect format"); + break; } - return length; } -@ @c long cff_pack_fdselect(cff_font * cff, card8 * dest, long destlen) { cff_fdselect *fdsel; long len = 0; card16 i; - if (cff->fdselect == NULL) return 0; - if (destlen < 1) normal_error("cff","buffer overflow (23)"); - fdsel = cff->fdselect; - dest[len++] = fdsel->format; switch (fdsel->format) { - case 0: - if (fdsel->num_entries != cff->num_glyphs) - normal_error("cff","invalid data"); - if (destlen < len + fdsel->num_entries) - normal_error("cff","buffer overflow (24)"); - for (i = 0; i < fdsel->num_entries; i++) { - dest[len++] = (fdsel->data).fds[i]; - } - break; - case 3: - { - if (destlen < len + 2) - normal_error("cff","buffer overflow (25)"); - len += 2; - for (i = 0; i < (fdsel->num_entries); i++) { - if (destlen < len + 3) - normal_error("cff","buffer overflow (26)"); - dest[len++] = - (card8) (((fdsel->data).ranges[i].first >> 8) & 0xff); - dest[len++] = (card8) ((fdsel->data).ranges[i].first & 0xff); - dest[len++] = (card8) ((fdsel->data).ranges[i].fd); + case 0: + if (fdsel->num_entries != cff->num_glyphs) + normal_error("cff","invalid data"); + if (destlen < len + fdsel->num_entries) + normal_error("cff","buffer overflow (24)"); + for (i = 0; i < fdsel->num_entries; i++) { + dest[len++] = (fdsel->data).fds[i]; } - if (destlen < len + 2) - normal_error("cff","buffer overflow (27)"); - dest[len++] = (card8) ((cff->num_glyphs >> 8) & 0xff); - dest[len++] = (card8) (cff->num_glyphs & 0xff); - dest[1] = (card8) (((len / 3 - 1) >> 8) & 0xff); - dest[2] = (card8) ((len / 3 - 1) & 0xff); - } - break; - default: - normal_error("cff","unknown FDSelect format"); - break; + break; + case 3: + { + if (destlen < len + 2) + normal_error("cff","buffer overflow (25)"); + len += 2; + for (i = 0; i < (fdsel->num_entries); i++) { + if (destlen < len + 3) + normal_error("cff","buffer overflow (26)"); + dest[len++] = + (card8) (((fdsel->data).ranges[i].first >> 8) & 0xff); + dest[len++] = (card8) ((fdsel->data).ranges[i].first & 0xff); + dest[len++] = (card8) ((fdsel->data).ranges[i].fd); + } + if (destlen < len + 2) + normal_error("cff","buffer overflow (27)"); + dest[len++] = (card8) ((cff->num_glyphs >> 8) & 0xff); + dest[len++] = (card8) (cff->num_glyphs & 0xff); + dest[1] = (card8) (((len / 3 - 1) >> 8) & 0xff); + dest[2] = (card8) ((len / 3 - 1) & 0xff); + } + break; + default: + normal_error("cff","unknown FDSelect format"); + break; } - return len; } -@ Create an instance of embeddable font. +/*tex Create an instance of embeddable font. */ -@c static void write_fontfile(PDF pdf, cff_font * cffont, char *fullname) { cff_index *topdict, *fdarray, *private; unsigned char *dest; long destlen = 0, i, size; long offset, topdict_offset, fdarray_offset; - - /* DICT sizes (offset set to long int) */ topdict = cff_new_index(1); fdarray = cff_new_index(cffont->num_fds); private = cff_new_index(cffont->num_fds); - cff_dict_remove(cffont->topdict, "UniqueID"); cff_dict_remove(cffont->topdict, "XUID"); - cff_dict_remove(cffont->topdict, "Private"); /* some bad font may have */ - cff_dict_remove(cffont->topdict, "Encoding"); /* some bad font may have */ - cff_dict_remove(cffont->topdict, "vstore"); /* cff2 */ - cff_dict_remove(cffont->topdict, "maxstack"); /* cff2 */ - + /*tex A bad font may have this: */ + cff_dict_remove(cffont->topdict, "Private"); + /*tex A bad font may have this: */ + cff_dict_remove(cffont->topdict, "Encoding"); + /*tex This is CFF2 specific: */ + cff_dict_remove(cffont->topdict, "vstore"); + /*tex This is CFF2 specific: */ + cff_dict_remove(cffont->topdict, "maxstack"); topdict->offset[1] = (l_offset) cff_dict_pack(cffont->topdict, (card8 *) work_buffer, WORK_BUFFER_SIZE) + 1; for (i = 0; i < cffont->num_fds; i++) { size = 0; if (cffont->private && cffont->private[i]) { size = cff_dict_pack(cffont->private[i], (card8 *) work_buffer, WORK_BUFFER_SIZE); if (size < 1) { - /* Private had contained only Subr. */ + /*tex |Private| contains only |Subr|: */ cff_dict_remove(cffont->fdarray[i], "Private"); } } - (private->offset)[i + 1] = (unsigned long) ((private->offset)[i] - + (unsigned) size); + (private->offset)[i + 1] = (unsigned long) ((private->offset)[i] + (unsigned) size); (fdarray->offset)[i + 1] = (unsigned long) ((fdarray->offset)[i] + (unsigned) cff_dict_pack(cffont->fdarray[i], (card8 *) work_buffer, WORK_BUFFER_SIZE)); } - - destlen = 4; /* header size */ + /*tex The header size: */ + destlen = 4; destlen += cff_set_name(cffont, fullname); destlen += cff_index_size(topdict); destlen += cff_index_size(cffont->string); destlen += cff_index_size(cffont->gsubr); - destlen += (cffont->charsets->num_entries) * 2 + 1; /* charset format 0 */ - destlen += (cffont->fdselect->num_entries) * 3 + 5; /* fdselect format 3 */ + /*tex |charset| format 0 */ + destlen += (cffont->charsets->num_entries) * 2 + 1; + /*tex |fdselect| format 3 */ + destlen += (cffont->fdselect->num_entries) * 3 + 5; destlen += cff_index_size(cffont->cstrings); destlen += cff_index_size(fdarray); - destlen = (long) (destlen + (long) private->offset[private->count] - 1); /* Private is not INDEX */ + /* |Private| is not indexed */ + destlen = (long) (destlen + (long) private->offset[private->count] - 1); dest = xcalloc((unsigned) destlen, sizeof(card8)); - offset = 0; - /* Header */ + /*tex |Header| */ offset += cff_put_header(cffont, dest + offset, destlen - offset); - /* Name */ + /*tex |Name| */ offset += cff_pack_index(cffont->name, dest + offset, destlen - offset); - /* Top DICT */ + /*tex |Top DICT| */ topdict_offset = offset; offset += cff_index_size(topdict); - /* Strings */ + /*tex |Strings| */ offset += cff_pack_index(cffont->string, dest + offset, destlen - offset); - /* Global Subrs */ + /*tex |Global Subrs| */ offset += cff_pack_index(cffont->gsubr, dest + offset, destlen - offset); - /* charset */ + /*tex |charset| */ cff_dict_set(cffont->topdict, "charset", 0, (double) offset); offset += cff_pack_charsets(cffont, dest + offset, destlen - offset); - /* FDSelect */ + /*tex |FDSelect| */ cff_dict_set(cffont->topdict, "FDSelect", 0, (double) offset); offset += cff_pack_fdselect(cffont, dest + offset, destlen - offset); - /* CharStrings */ + /*tex |CharStrings| */ cff_dict_set(cffont->topdict, "CharStrings", 0, (double) offset); offset += cff_pack_index(cffont->cstrings, dest + offset, cff_index_size(cffont->cstrings)); cff_release_index(cffont->cstrings); - cffont->cstrings = NULL; /* Charstrings cosumes huge memory */ - /* FDArray and Private */ + /*tex |Charstring|s can consume a lot of memory. */ + cffont->cstrings = NULL; + /*tex |FDArray| and |Private| */ cff_dict_set(cffont->topdict, "FDArray", 0, (double) offset); fdarray_offset = offset; offset += cff_index_size(fdarray); - fdarray->data = xcalloc((unsigned) (fdarray->offset[fdarray->count] - 1), sizeof(card8)); for (i = 0; i < cffont->num_fds; i++) { size = (long) (private->offset[i + 1] - private->offset[i]); @@ -2792,53 +2640,39 @@ static void write_fontfile(PDF pdf, cff_font * cffont, char *fullname) cff_pack_index(fdarray, dest + fdarray_offset, cff_index_size(fdarray)); cff_release_index(fdarray); cff_release_index(private); - - /* Finally Top DICT */ + /*tex Finally the |Top DICT| */ topdict->data = xcalloc((unsigned) (topdict->offset[topdict->count] - 1), sizeof(card8)); cff_dict_pack(cffont->topdict, topdict->data, (long) (topdict->offset[topdict->count] - 1)); cff_pack_index(topdict, dest + topdict_offset, cff_index_size(topdict)); cff_release_index(topdict); - for (i = 0; i < offset; i++) { -// printf("%i\n",(unsigned char)dest[i]); strbuf_putchar(pdf->fb, dest[i]); } xfree(dest); return; } -@ @c void write_cff(PDF pdf, cff_font * cffont, fd_entry * fd) { cff_index *charstrings, *cs_idx; - long charstring_len, max_len; long size, offset = 0; - card8 *data; card16 num_glyphs, cs_count1, code, gid, last_cid; - double nominal_width, default_width; - char *fontname; char *fullname; - glw_entry *glyph, *found; struct avl_traverser t; - -cffont->_string = NULL; - + cffont->_string = NULL; fontname = xcalloc((unsigned) (1 + strlen(fd->fontname)), 1); sprintf(fontname, "%s", fd->fontname); - fullname = xcalloc((unsigned) (8 + strlen(fd->fontname)), 1); sprintf(fullname, "%s+%s", fd->subset_tag, fd->fontname); - - /* finish parsing the CFF */ + /*tex Finish parsing the CFF. */ cff_read_private(cffont); cff_read_subrs(cffont); - - /* Widths */ + /*tex The |Width|s. */ if (cffont->private[0] && cff_dict_known(cffont->private[0], "defaultWidthX")) { default_width = (double) cff_dict_get(cffont->private[0], "defaultWidthX", 0); } else { @@ -2849,18 +2683,15 @@ cffont->_string = NULL; } else { nominal_width = CFF_NOMINALWIDTHX_DEFAULT; } - num_glyphs = 0; last_cid = 0; glyph = xtalloc(1, glw_entry); - - /* insert notdef */ + /*tex insert |notdef| */ glyph->id = 0; if (avl_find(fd->gl_tree, glyph) == NULL) { avl_insert(fd->gl_tree, glyph); glyph = xtalloc(1, glw_entry); } - avl_t_init(&t, fd->gl_tree); for (found = (glw_entry *) avl_t_first(&t, fd->gl_tree); found != NULL; found = (glw_entry *) avl_t_next(&t)) { @@ -2868,10 +2699,8 @@ cffont->_string = NULL; last_cid = (card16) found->id; num_glyphs++; } - { cff_fdselect *fdselect; - fdselect = xcalloc(1, sizeof(cff_fdselect)); fdselect->format = 3; fdselect->num_entries = 1; @@ -2880,17 +2709,13 @@ cffont->_string = NULL; fdselect->data.ranges[0].fd = 0; cffont->fdselect = fdselect; } - { cff_charsets *charset; - charset = xcalloc(1, sizeof(cff_charsets)); charset->format = 0; charset->num_entries = (card16) (num_glyphs - 1); charset->data.glyphs = xcalloc(num_glyphs, sizeof(s_SID)); - gid = 0; - avl_t_init(&t, fd->gl_tree); for (found = (glw_entry *) avl_t_first(&t, fd->gl_tree); found != NULL; found = (glw_entry *) avl_t_next(&t)) { @@ -2900,64 +2725,53 @@ cffont->_string = NULL; } } cffont->charsets = charset; - if (cffont->header_major == 2) { cff_dict_add(cffont->topdict, "charset", 1); } } cff_dict_add(cffont->topdict, "CIDCount", 1); cff_dict_set(cffont->topdict, "CIDCount", 0, last_cid + 1); - if (cffont->header_major == 2) { - cff_dict_add(cffont->topdict, "FullName", 1); cff_dict_set(cffont->topdict, "FullName", 0, (double) cff_add_string(cffont, fontname)); - cff_dict_add(cffont->topdict, "FontBBox", 4); cff_dict_set(cffont->topdict, "FontBBox", 0, fd->font_dim[FONTBBOX1_CODE].val); cff_dict_set(cffont->topdict, "FontBBox", 1, fd->font_dim[FONTBBOX2_CODE].val); cff_dict_set(cffont->topdict, "FontBBox", 2, fd->font_dim[FONTBBOX3_CODE].val); cff_dict_set(cffont->topdict, "FontBBox", 3, fd->font_dim[FONTBBOX4_CODE].val); } - cffont->fdarray = xcalloc(1, sizeof(cff_dict *)); cffont->fdarray[0] = cff_new_dict(); cff_dict_add(cffont->fdarray[0], "FontName", 1); - /* FIXME: Skip XXXXXX+ */ + /*tex fix: skip XXXXXX+ */ cff_dict_set(cffont->fdarray[0], "FontName", 0, (double) cff_add_string(cffont, fullname)); cff_dict_add(cffont->fdarray[0], "Private", 2); cff_dict_set(cffont->fdarray[0], "Private", 0, 0.0); cff_dict_set(cffont->fdarray[0], "Private", 0, 0.0); - /* FDArray - index offset, not known yet */ + /*tex |FDArray| index offset, not known yet */ cff_dict_add(cffont->topdict, "FDArray", 1); cff_dict_set(cffont->topdict, "FDArray", 0, 0.0); - /* FDSelect - offset, not known yet */ + /*tex |FDSelect| offset, not known yet */ cff_dict_add(cffont->topdict, "FDSelect", 1); cff_dict_set(cffont->topdict, "FDSelect", 0, 0.0); - cff_dict_remove(cffont->topdict, "UniqueID"); cff_dict_remove(cffont->topdict, "XUID"); cff_dict_remove(cffont->topdict, "Private"); cff_dict_remove(cffont->topdict, "Encoding"); - cffont->offset = (l_offset) cff_dict_get(cffont->topdict, "CharStrings", 0); cs_idx = cff_get_index_header(cffont); - offset = (long) cffont->offset; cs_count1 = cs_idx->count; if (cs_count1 < 2) { normal_error("cff","no valid charstring data found"); } - - /* build the new charstrings entry */ + /*tex Build the new charstrings entry. */ charstrings = cff_new_index((card16) (cs_count1==USHRT_MAX?cs_count1: cs_count1 + 1)); max_len = 2 * CS_STR_LEN_MAX; charstrings->data = xcalloc((unsigned) max_len, sizeof(card8)); charstring_len = 0; - gid = 0; data = xcalloc(CS_STR_LEN_MAX, sizeof(card8)); - { int i; int tex_font = fd->tex_font; @@ -2971,7 +2785,7 @@ cffont->_string = NULL; code = (card16) i; glyph->id = code; if ((avl_find(fd->gl_tree,glyph) != NULL)) { - /* this code is the same as below, apart from small details */ + /*tex This code is the same as below, apart from small details */ if (callback_id > 0) { lstring * result; run_callback(callback_id, "ddd->L", tex_font, i, streamprovider, &result); /* this call can be sped up */ @@ -2982,7 +2796,7 @@ cffont->_string = NULL; charstrings->data = xrealloc(charstrings->data, (unsigned)((unsigned)max_len*sizeof(card8))); } (charstrings->offset)[gid] = (unsigned)(charstring_len + 1); - cffont->offset = (l_offset)((unsigned)offset + (cs_idx->offset)[code] - 1); + cffont->offset = (l_offset)((unsigned)offset + (cs_idx->offset)[code] - 1); memcpy(charstrings->data+charstring_len,(const char *) result->s,(size_t) size); charstring_len += size; xfree(result); @@ -3012,9 +2826,9 @@ cffont->_string = NULL; } } } - /* - CIDSet: a table of bits indexed by cid, bytes with high order bit first, - each (set) bit is a (present) CID. + /*tex + The |CIDSet| is a table of bits indexed by cid, bytes with high order bit + first, each (set) bit is a (present) CID. */ if (1) { int cid; @@ -3039,123 +2853,101 @@ cffont->_string = NULL; pdf_end_obj(pdf); } } - /* - This happens if the internal metrics do not agree with the actual - disk font. + /*tex + This happens if the internal metrics do not agree with the actual disk + font. */ if (gid < num_glyphs) { formatted_warning("cff","embedded subset is smaller than expected: %d instead of %d glyphs", gid, num_glyphs); num_glyphs = gid; } - xfree(data); cff_release_index(cs_idx); - (charstrings->offset)[num_glyphs] = (l_offset) (charstring_len + 1); charstrings->count = num_glyphs; cffont->num_glyphs = num_glyphs; cffont->cstrings = charstrings; - /* + /*tex We don't use subroutines at all. */ if (cffont->gsubr) cff_release_index(cffont->gsubr); cffont->gsubr = cff_new_index(0); - if (cffont->subrs && cffont->subrs[0]) cff_release_index(cffont->subrs[0]); cffont->subrs[0] = NULL; - if (cffont->private && (cffont->private)[0]) { cff_dict_remove((cffont->private)[0], "Subrs"); /* no Subrs */ } - cff_dict_update(cffont->topdict, cffont); - cff_add_string(cffont, "Adobe"); cff_add_string(cffont, "Identity"); if (cffont->header_major == 2) { - /* crash */ + /*tex A crash. */ } else { cff_dict_update(cffont->private[0], cffont); } cff_update_string(cffont); - /* CFF code need to be rewritten */ cff_dict_add(cffont->topdict, "ROS", 3); cff_dict_set(cffont->topdict, "ROS", 0, (double) cff_get_sid(cffont, "Adobe")); cff_dict_set(cffont->topdict, "ROS", 1, (double) cff_get_sid(cffont, "Identity")); cff_dict_set(cffont->topdict, "ROS", 2, 0.0); - write_fontfile(pdf, cffont, fullname); xfree(fontname); xfree(fullname); cff_close(cffont); } -@ @c #define is_cidfont(a) ((a)->flag & FONTTYPE_CIDFONT) #define CID_MAX 65535 void write_cid_cff(PDF pdf, cff_font * cffont, fd_entry * fd) { cff_index *charstrings, *cs_idx; - long charstring_len, max_len; long size, offset = 0; int tex_font = fd->tex_font; int streamprovider = 0; int callback_id = 0 ; - card8 *data; card16 num_glyphs, cs_count1, gid, last_cid; - int fdsel, prev_fd, cid_count, cid ; char *fullname; - glw_entry *glyph; - unsigned char *CIDToGIDMap = NULL; - cff_fdselect *fdselect = NULL; cff_charsets *charset = NULL; - if (!is_cidfont(cffont)) { normal_error("cff","invalid CIDfont"); return; } - if ((tex_font > 0) && (font_streamprovider(tex_font) == 1)) { streamprovider = font_streamprovider(tex_font); callback_id = callback_defined(glyph_stream_provider_callback); } - fullname = xcalloc((unsigned) (8 + strlen(fd->fontname)), 1); sprintf(fullname, "%s+%s", fd->subset_tag, fd->fontname); - - /* finish parsing the CFF */ - + /*tex Finish parsing the CFF. */ if (cff_dict_known(cffont->topdict, "CIDCount")) { cid_count = (card16) cff_dict_get(cffont->topdict, "CIDCount", 0); } else { cid_count = CFF_CIDCOUNT_DEFAULT; } if (cffont->header_major == 2) { - /* hm */ + /*tex hm */ } else { cff_read_charsets(cffont); } CIDToGIDMap = xmalloc((unsigned) ((2 * (unsigned) cid_count) * sizeof(unsigned char))); memset(CIDToGIDMap, 0, (size_t) (2 * cid_count)); - glyph = xtalloc(1, glw_entry); - /* insert notdef */ + /*tex insert |notdef| */ glyph->id = 0; if (avl_find(fd->gl_tree, glyph) == NULL) { avl_insert(fd->gl_tree, glyph); glyph = xtalloc(1, glw_entry); } - last_cid = 0; num_glyphs = 0; for (cid = 0; cid <= CID_MAX; cid++) { @@ -3169,13 +2961,13 @@ void write_cid_cff(PDF pdf, cff_font * cffont, fd_entry * fd) } } if (cffont->header_major == 2) { - /* hm */ + /*tex hm */ } else if (last_cid >= cffont->num_glyphs) { formatted_error("cff font","bad glyph index %i",last_cid); } - /* - CIDSet: a table of bits indexed by cid, bytes with high order bit - first, each (set) bit is a (present) CID. + /*tex + The |CIDSet| table is a table of bits indexed by cid, bytes with high + order bit first, each (set) bit is a (present) CID. */ if (1) { cidset = pdf_create_obj(pdf, obj_type_others, 0); @@ -3196,57 +2988,46 @@ void write_cid_cff(PDF pdf, cff_font * cffont, fd_entry * fd) pdf_out_block(pdf, stream, l); pdf_end_stream(pdf); pdf_end_obj(pdf); - xfree(stream); + xfree(stream); } } - cff_read_fdselect(cffont); cff_read_fdarray(cffont); cff_read_private(cffont); - cff_read_subrs(cffont); - cffont->offset = (l_offset) cff_dict_get(cffont->topdict, "CharStrings", 0); cs_idx = cff_get_index_header(cffont); - offset = (long) cffont->offset; cs_count1 = cs_idx->count; if (cs_count1 < 2) { normal_error("cff","no valid charstring data found"); } - charset = xcalloc(1, sizeof(cff_charsets)); charset->format = 0; charset->num_entries = 0; charset->data.glyphs = xcalloc(num_glyphs, sizeof(s_SID)); - fdselect = xcalloc(1, sizeof(cff_fdselect)); fdselect->format = 3; fdselect->num_entries = 0; fdselect->data.ranges = xcalloc(num_glyphs, sizeof(cff_range3)); - charstrings = cff_new_index((card16) (cs_count1==USHRT_MAX?cs_count1: cs_count1 + 1)); max_len = 2 * CS_STR_LEN_MAX; charstrings->data = xcalloc((unsigned) max_len, sizeof(card8)); charstring_len = 0; - prev_fd = -1; gid = 0; data = xcalloc(CS_STR_LEN_MAX, sizeof(card8)); for (cid = 0; cid <= last_cid; cid++) { unsigned short gid_org; - glyph->id = (unsigned) cid; if (avl_find(fd->gl_tree, glyph) == NULL) continue; - gid_org = (short unsigned) ((CIDToGIDMap[2 * cid] << 8) | (CIDToGIDMap[2 * cid + 1])); fdsel = cff_fdselect_lookup(cffont, gid_org); - if (callback_id > 0) { - /* the next blob is not yet tested ... i need a font */ + /*tex The next blob is not yet tested \unknown\ I need a font. */ lstring * result; - run_callback(callback_id, "ddd->L", tex_font, gid_org, streamprovider, &result); /* this call can be sped up */ + run_callback(callback_id, "ddd->L", tex_font, gid_org, streamprovider, &result); size = (size_t) result->l ; if (size > 0) { if (charstring_len + CS_STR_LEN_MAX >= max_len) { @@ -3254,7 +3035,7 @@ void write_cid_cff(PDF pdf, cff_font * cffont, fd_entry * fd) charstrings->data = xrealloc(charstrings->data, (unsigned)((unsigned)max_len*sizeof(card8))); } (charstrings->offset)[gid] = (unsigned)(charstring_len + 1); - cffont->offset = (l_offset)((unsigned)offset + (cs_idx->offset)[gid_org] - 1); + cffont->offset = (l_offset)((unsigned)offset + (cs_idx->offset)[gid_org] - 1); memcpy(charstrings->data+charstring_len,(const char *) result->s,(size_t)size); charstring_len += size; xfree(result); @@ -3292,14 +3073,11 @@ void write_cid_cff(PDF pdf, cff_font * cffont, fd_entry * fd) } gid++; } - if (gid != num_glyphs) formatted_error("cff","unexpected error: %i != %i", gid, num_glyphs); xfree(data); cff_release_index(cs_idx); - xfree(CIDToGIDMap); - (charstrings->offset)[num_glyphs] = (l_offset) (charstring_len + 1); charstrings->count = num_glyphs; cffont->num_glyphs = num_glyphs; @@ -3308,13 +3086,12 @@ void write_cid_cff(PDF pdf, cff_font * cffont, fd_entry * fd) cffont->charsets = charset; cff_release_fdselect(cffont->fdselect); cffont->fdselect = fdselect; - /* + /*tex We don't use subroutines at all. */ if (cffont->gsubr) cff_release_index(cffont->gsubr); cffont->gsubr = cff_new_index(0); - for (fdsel = 0; fdsel < cffont->num_fds; fdsel++) { if (cffont->subrs && cffont->subrs[fdsel]) { cff_release_index(cffont->subrs[fdsel]); @@ -3329,11 +3106,14 @@ void write_cid_cff(PDF pdf, cff_font * cffont, fd_entry * fd) cff_close(cffont); } -@ Here is a sneaky trick: fontforge knows how to convert Type1 to CFF, so -I have defined a utility function in luafflib.c that does exactly that. -If it works out ok, I will clean up this code. +/*tex + + Here is a sneaky trick: fontforge knows how to convert Type1 to CFF, so I + have defined a utility function in luafflib.c that does exactly that. If it + works out ok, I will clean up this code. + +*/ -@c void writetype1w(PDF pdf, fd_entry * fd) { cff_font *cff; @@ -3342,24 +3122,19 @@ void writetype1w(PDF pdf, fd_entry * fd) ff_entry *ff; unsigned char *tfm_buffer = NULL; int tfm_size = 0; - ff = check_ff_exist(fd->fm->ff_name, 0); - fp = fopen(ff->ff_path, "rb"); cur_file_name = ff->ff_path; - if (!fp) { formatted_error("cff","could not open Type1 font: %s", cur_file_name); } fclose(fp); - if (is_subsetted(fd->fm)) { report_start_file(filetype_subset,cur_file_name); } else { report_start_file(filetype_font,cur_file_name); } (void) ff_createcff(ff->ff_path, &tfm_buffer, &tfm_size); - if (tfm_size > 0) { cff = read_cff(tfm_buffer, tfm_size, 0); if (cff != NULL) { diff --git a/Build/source/texk/web2c/luatexdir/font/writeenc.w b/Build/source/texk/web2c/luatexdir/font/writeenc.c index 1a7ed3891af..554c246a5dc 100644 --- a/Build/source/texk/web2c/luatexdir/font/writeenc.w +++ b/Build/source/texk/web2c/luatexdir/font/writeenc.c @@ -1,34 +1,37 @@ -% writeenc.w -% -% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org> -% Copyright 2006-2011 Taco Hoekwater <taco@@luatex.org> -% -% This file is part of LuaTeX. -% -% LuaTeX 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. -% -% LuaTeX 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 Lesser General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License along -% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. - -@ @c +/* +Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> +Copyright 2006-2011 Taco Hoekwater <taco@luatex.org> + +This file is part of LuaTeX. + +LuaTeX 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. + +LuaTeX 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU General Public License along +with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +*/ #include "ptexlib.h" -@ All encoding entries go into AVL tree for fast search by name. -@c +/*tex + + All encoding entries go into AVL tree for fast search by name. + +*/ + struct avl_table *fe_tree = NULL; -@ AVL sort |fe_entry| into |fe_tree| by name -@c +/* The AVL sort |fe_entry| into |fe_tree| by name. */ + static int comp_fe_entry(const void *pa, const void *pb, void *p) { (void) p; @@ -41,7 +44,8 @@ static fe_entry *new_fe_entry(void) fe = xtalloc(1, fe_entry); fe->name = NULL; fe->fe_objnum = 0; - fe->glyph_names = NULL; /* encoding file not yet read in */ + /*tex The encoding file is not yet read in. */ + fe->glyph_names = NULL; fe->tx_tree = NULL; return fe; } @@ -67,7 +71,8 @@ static void register_fe_entry(fe_entry * fe) } assert(fe != NULL); assert(fe->name != NULL); - assert(lookup_fe_entry(fe->name) == NULL); /* encoding not yet registered */ + /*tex The encoding is not yet registered. */ + assert(lookup_fe_entry(fe->name) == NULL); aa = avl_probe(fe_tree, fe); assert(aa != NULL); } @@ -85,9 +90,7 @@ fe_entry *get_fe_entry(char *s) return fe; } -@ @c -static void write_enc(PDF pdf, char **glyph_names, struct avl_table *tx_tree, - int fe_objnum) +static void write_enc(PDF pdf, char **glyph_names, struct avl_table *tx_tree, int fe_objnum) { int i_old, *p; struct avl_traverser t; @@ -102,9 +105,9 @@ static void write_enc(PDF pdf, char **glyph_names, struct avl_table *tx_tree, avl_t_init(&t, tx_tree); for (i_old = -2, p = (int *) avl_t_first(&t, tx_tree); p != NULL; p = (int *) avl_t_next(&t)) { - if (*p == i_old + 1) /* consecutive */ + if (*p == i_old + 1) { pdf_add_name(pdf, glyph_names[*p]); - else { + } else { pdf_add_int(pdf, *p); pdf_add_name(pdf, glyph_names[*p]); } @@ -134,8 +137,7 @@ void write_fontencodings(PDF pdf) write_fontencoding(pdf, fe); } -@ cleaning up... -@c +/*tex Cleaning up \unknown */ static void destroy_fe_entry(void *pa, void *pb) { diff --git a/Build/source/texk/web2c/luatexdir/font/writefont.w b/Build/source/texk/web2c/luatexdir/font/writefont.c index 2ba81d61749..5d75ef80cc7 100644 --- a/Build/source/texk/web2c/luatexdir/font/writefont.w +++ b/Build/source/texk/web2c/luatexdir/font/writefont.c @@ -1,69 +1,69 @@ -% writefont.w -% -% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org> -% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org> -% -% This file is part of LuaTeX. -% -% LuaTeX 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. -% -% LuaTeX 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 Lesser General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License along -% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. - -@ @c +/* + +Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> +Copyright 2006-2010 Taco Hoekwater <taco@luatex.org> + +This file is part of LuaTeX. + +LuaTeX 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. + +LuaTeX 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 Lesser General Public +License for more details. +You should have received a copy of the GNU General Public License along +with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +*/ #include "ptexlib.h" #include "lua/luatex-api.h" void write_cid_fontdictionary(PDF pdf, fo_entry * fo, internal_font_number f); + static void create_cid_fontdictionary(PDF pdf, internal_font_number f); const key_entry font_key[FONT_KEYS_NUM] = { - { "Ascent", "Ascender", 1 }, - { "CapHeight", "CapHeight", 1 }, - { "Descent", "Descender", 1 }, + { "Ascent", "Ascender", 1 }, + { "CapHeight", "CapHeight", 1 }, + { "Descent", "Descender", 1 }, { "ItalicAngle", "ItalicAngle", 1 }, - { "StemV", "StdVW", 1 }, - { "XHeight", "XHeight", 1 }, - { "FontBBox", "FontBBox", 1 }, - { "", "", 0 }, - { "", "", 0 }, - { "", "", 0 }, - { "FontName", "FontName", 1 } + { "StemV", "StdVW", 1 }, + { "XHeight", "XHeight", 1 }, + { "FontBBox", "FontBBox", 1 }, + { "", "", 0 }, + { "", "", 0 }, + { "", "", 0 }, + { "FontName", "FontName", 1 } }; -@ -@c -struct avl_table *fo_tree = NULL; /* tree of font dictionaries */ -struct avl_table *fd_tree = NULL; /* tree of font descriptor objects */ +/*tex A tree of font dictionaries: */ + +struct avl_table *fo_tree = NULL; + +/*tex A tree of font descriptor objects: */ + +struct avl_table *fd_tree = NULL; static int comp_fo_entry(const void *pa, const void *pb, void *p) { (void) p; - return strcmp(((const fo_entry *) pa)->fm->tfm_name, - ((const fo_entry *) pb)->fm->tfm_name); + return strcmp(((const fo_entry *) pa)->fm->tfm_name, ((const fo_entry *) pb)->fm->tfm_name); } static int comp_fd_entry(const void *pa, const void *pb, void *p) { const fd_entry *p1 = (const fd_entry *) pa, *p2 = (const fd_entry *) pb; (void) p; - assert(p1->fm != NULL && is_fontfile(p1->fm) && - p2->fm != NULL && is_fontfile(p2->fm)); return strcmp(p1->fm->ff_name, p2->fm->ff_name); } -@ initialize data structure for /Type /Font -@c +/*tex We initialize data structure for |/Type| |/Font|: */ + static fo_entry *new_fo_entry(void) { fo_entry *fo; @@ -81,8 +81,8 @@ static fo_entry *new_fo_entry(void) return fo; } -@ initialize data structure for /Type /FontDescriptor -@c +/*tex We initialize data structure for |/Type| |/FontDescriptor|: */ + fd_entry *new_fd_entry(internal_font_number f) { fd_entry *fd; @@ -108,12 +108,14 @@ fd_entry *new_fd_entry(internal_font_number f) return fd; } -@ -Only fallback values of font metrics are taken from the TFM info -of |f| by |preset_fontmetrics|. During reading of the font file, -these values are replaced by metrics from the font, if available. +/*tex + + Only fallback values of font metrics are taken from the TFM info of |f| by + |preset_fontmetrics|. During reading of the font file, these values are + replaced by metrics from the font, if available. + +*/ -@c static void preset_fontmetrics(fd_entry * fd, internal_font_number f) { int i; @@ -143,9 +145,7 @@ static void fix_fontmetrics(fd_entry * fd) { int i; intparm *p = (intparm *) fd->font_dim; - assert(p[FONTBBOX1_CODE].set && p[FONTBBOX2_CODE].set - && p[FONTBBOX3_CODE].set && p[FONTBBOX4_CODE].set); - /* make sure there is a rectangle */ + /*tex Make sure there is a rectangle. */ if (p[FONTBBOX3_CODE].val < p[FONTBBOX1_CODE].val) { i = p[FONTBBOX3_CODE].val; p[FONTBBOX3_CODE].val = p[FONTBBOX1_CODE].val; @@ -178,34 +178,41 @@ static void write_fontmetrics(PDF pdf, fd_entry * fd) fix_fontmetrics(fd); pdf_add_name(pdf, font_key[FONTBBOX1_CODE].pdfname); pdf_begin_array(pdf); - pdf_printf(pdf, "%i %i %i %i", (int) fd->font_dim[FONTBBOX1_CODE].val, - (int) fd->font_dim[FONTBBOX2_CODE].val, - (int) fd->font_dim[FONTBBOX3_CODE].val, - (int) fd->font_dim[FONTBBOX4_CODE].val); + /* + pdf_check_space; + pdf_printf(pdf, "%i %i %i %i", + (int) fd->font_dim[FONTBBOX1_CODE].val, + (int) fd->font_dim[FONTBBOX2_CODE].val, + (int) fd->font_dim[FONTBBOX3_CODE].val, + (int) fd->font_dim[FONTBBOX4_CODE].val); + */ + pdf_add_int(pdf,(int) fd->font_dim[FONTBBOX1_CODE].val); + pdf_add_int(pdf,(int) fd->font_dim[FONTBBOX2_CODE].val); + pdf_add_int(pdf,(int) fd->font_dim[FONTBBOX3_CODE].val); + pdf_add_int(pdf,(int) fd->font_dim[FONTBBOX4_CODE].val); + /* */ pdf_end_array(pdf); for (i = 0; i < GEN_KEY_NUM; i++) if (fd->font_dim[i].set) pdf_dict_add_int(pdf, font_key[i].pdfname, fd->font_dim[i].val); } -@ -@c static void preset_fontname(fo_entry * fo, internal_font_number f) { - if (fo->fm->ps_name != NULL) - fo->fd->fontname = xstrdup(fo->fm->ps_name); /* just fallback */ - else if (font_fullname(f) != NULL) + if (fo->fm->ps_name != NULL) { + /*tex We just fallback. */ + fo->fd->fontname = xstrdup(fo->fm->ps_name); + } else if (font_fullname(f) != NULL) { fo->fd->fontname = xstrdup(font_fullname(f)); - else + } else { fo->fd->fontname = xstrdup(fo->fm->tfm_name); + } } static void pdf_dict_add_fontname(PDF pdf, const char *key, fd_entry * fd) { char *s; size_t l1 = 0, l2; - assert(fd->fontname != NULL); - assert(key != NULL); if (fd->subset_tag != NULL) l1 = strlen(fd->subset_tag); l2 = strlen(fd->fontname); @@ -218,27 +225,20 @@ static void pdf_dict_add_fontname(PDF pdf, const char *key, fd_entry * fd) xfree(s); } -@ -@c fd_entry *lookup_fd_entry(char *s) { fd_entry fd; fm_entry fm; - assert(s != NULL); fm.ff_name = s; fd.fm = &fm; if (fd_tree == NULL) { fd_tree = avl_create(comp_fd_entry, NULL, &avl_xallocator); - assert(fd_tree != NULL); } return (fd_entry *) avl_find(fd_tree, &fd); } static fd_entry *lookup_fontdescriptor(fo_entry * fo) { - assert(fo != NULL); - assert(fo->fm != NULL); - assert(is_fontfile(fo->fm)); return lookup_fd_entry(fo->fm->ff_name); } @@ -247,66 +247,72 @@ void register_fd_entry(fd_entry * fd) void **aa; if (fd_tree == NULL) { fd_tree = avl_create(comp_fd_entry, NULL, &avl_xallocator); - assert(fd_tree != NULL); } - assert(fd != NULL && fd->fm != NULL && is_fontfile(fd->fm)); - /* font descriptor not yet registered: */ - assert(lookup_fd_entry(fd->fm->ff_name) == NULL); + /*tex The font descriptor is not yet registered: */ + if (lookup_fd_entry(fd->fm->ff_name) == NULL) { + /*tex Is this a problem? */ + } else { + /*tex The lookup also can create */ + } aa = avl_probe(fd_tree, fd); - assert(aa != NULL); + if (aa == NULL) { + /*tex Is this a problem? */ + } } static void create_fontdescriptor(fo_entry * fo, internal_font_number f) { - assert(fo != NULL); - assert(fo->fm != NULL); - assert(fo->fd == NULL); fo->fd = new_fd_entry(f); preset_fontname(fo, f); preset_fontmetrics(fo->fd, f); - /* encoding needed by TrueType writing: */ + /*tex An encoding is needed for \TRUETYPE\ writing: */ fo->fd->fe = fo->fe; - /* map entry needed by TrueType writing: */ + /*tex A map entry is needed for \TRUETYPE\ writing: */ fo->fd->fm = fo->fm; fo->fd->gl_tree = avl_create(comp_string_entry, NULL, &avl_xallocator); - assert(fo->fd->gl_tree != NULL); } -@ -For all used characters of \TeX font |f|, get corresponding glyph names -from external reencoding (.enc) file and collect these in the glyph -tree |gl_tree| of font descriptor |fd| referenced by font dictionary |fo|. +/*tex + + For all used characters of \TeX font |f|, get corresponding glyph names from + external reencoding (.enc) file and collect these in the glyph tree |gl_tree| + of font descriptor |fd| referenced by font dictionary |fo|. + +*/ -@c static void mark_reenc_glyphs(fo_entry * fo, internal_font_number f) { int i; char **g; void **aa; - assert(fo->fe != NULL); if (is_subsetted(fo->fm)) { - assert(is_included(fo->fm)); - /* mark glyphs from TeX (externally reencoded characters) */ + /*tex mark glyphs from TeX (externally reencoded characters) */ g = fo->fe->glyph_names; for (i = fo->first_char; i <= fo->last_char; i++) { if (pdf_char_marked(f, i) && g[i] != notdef && (char *) avl_find(fo->fd->gl_tree, g[i]) == NULL) { aa = avl_probe(fo->fd->gl_tree, xstrdup(g[i])); - assert(aa != NULL); + if (aa == NULL) { + /*tex Is this a problem? */ + } } } } } -@ -Function |mark_chars| has 2 uses: -\item 1. Mark characters as chars on \TeX\ level. -\item 2. Mark encoding pairs used by \TeX\ to optimize encoding vector. +/*tex + + Function |mark_chars| has 2 uses: -@c -static struct avl_table *mark_chars(fo_entry * fo, struct avl_table *tx_tree, - internal_font_number f) + \startitemize[n] + \startitem Mark characters as chars on \TeX\ level. \stopitem + \startitem Mark encoding pairs used by \TeX\ to optimize encoding vector. \stopitem + \stopitemize + +*/ + +static struct avl_table *mark_chars(fo_entry * fo, struct avl_table *tx_tree, internal_font_number f) { int i, *j; void **aa; @@ -319,19 +325,19 @@ static struct avl_table *mark_chars(fo_entry * fo, struct avl_table *tx_tree, j = xtalloc(1, int); *j = i; aa = avl_probe(tx_tree, j); - assert(aa != NULL); + if (aa == NULL) { + /*tex Is this a problem? */ + } } } return tx_tree; } -@ -@c static void get_char_range(fo_entry * fo, internal_font_number f) { int i; assert(fo != NULL); - /* search for |first_char| and |last_char| */ + /*tex Search for |first_char| and |last_char|. */ for (i = font_bc(f); i <= font_ec(f); i++) if (pdf_char_marked(f, i)) break; @@ -341,7 +347,7 @@ static void get_char_range(fo_entry * fo, internal_font_number f) break; fo->last_char = i; if ((fo->first_char > fo->last_char) || !pdf_char_marked(f, fo->first_char)) { - /* no character used from this font */ + /*tex No character has been used from this font. */ fo->last_char = 0; fo->first_char = fo->last_char + 1; } @@ -350,7 +356,7 @@ static void get_char_range(fo_entry * fo, internal_font_number f) static int font_has_subset(internal_font_number f) { int i, s; - /* search for |first_char| and |last_char| */ + /*tex Search for |first_char| and |last_char|. */ for (i = font_bc(f); i <= font_ec(f); i++) if (pdf_char_marked(f, i)) break; @@ -364,19 +370,14 @@ static int font_has_subset(internal_font_number f) return 1; } -@ -@c static void write_charwidth_array(PDF pdf, fo_entry * fo, internal_font_number f) { int i, j, *ip, *fip; struct avl_traverser t; - assert(fo->tx_tree != NULL); - assert(fo->cw_objnum == 0); fo->cw_objnum = pdf_create_obj(pdf, obj_type_others, 0); pdf_begin_obj(pdf, fo->cw_objnum, OBJSTM_ALWAYS); avl_t_init(&t, fo->tx_tree); fip = (int *) avl_t_first(&t, fo->tx_tree); - assert(fip != NULL); pdf_begin_array(pdf); for (ip = fip, j = *ip; ip != NULL; ip = (int *) avl_t_next(&t)) { if (ip != fip) @@ -393,19 +394,21 @@ static void write_charwidth_array(PDF pdf, fo_entry * fo, internal_font_number f pdf_end_obj(pdf); } -@ Remark: Font objects from embedded PDF files are never registered -into |fo_tree|; they are individually written out. -@c +/*tex + + Remark: Font objects from embedded PDF files are never registered into + |fo_tree|; they are individually written out. + +*/ + static fo_entry *lookup_fo_entry(char *s) { fo_entry fo; fm_entry fm; - assert(s != NULL); fm.tfm_name = s; fo.fm = &fm; if (fo_tree == NULL) { fo_tree = avl_create(comp_fo_entry, NULL, &avl_xallocator); - assert(fo_tree != NULL); } return (fo_entry *) avl_find(fo_tree, &fo); } @@ -415,60 +418,63 @@ static void register_fo_entry(fo_entry * fo) void **aa; if (fo_tree == NULL) { fo_tree = avl_create(comp_fo_entry, NULL, &avl_xallocator); - assert(fo_tree != NULL); } - assert(fo != NULL); - assert(fo->fm != NULL); - assert(fo->fm->tfm_name != NULL); - assert(lookup_fo_entry(fo->fm->tfm_name) == NULL); + if (lookup_fo_entry(fo->fm->tfm_name) == NULL) { + /*tex Is this a problem? */ + } else { + /*tex The lookup also can create */ + } aa = avl_probe(fo_tree, fo); - assert(aa != NULL); + if (aa == NULL) { + /*tex Is this a problem? */ + } } -@ -In principle we could replace the pdftex derived ttf.otf inclusion part -by using the regular code for this and assigning indices and tounicodes -to the character blobs, but for the moment we keep the current approach. -@c +/*tex + +In principle we could replace the pdftex derived ttf.otf inclusion part by using +the regular code for this and assigning indices and tounicodes to the character +blobs, but for the moment we keep the current approach. + +*/ + static void write_fontfile(PDF pdf, fd_entry * fd) { - assert(is_included(fd->fm)); if (is_cidkeyed(fd->fm)) { if (is_opentype(fd->fm)) { writetype0(pdf, fd); - } else if (is_truetype(fd->fm)) { + } else if (is_truetype(fd->fm)) { if (!writetype2(pdf, fd)) { writetype0(pdf,fd); - fd->fm->type |= F_OTF; fd->fm->type ^= F_TRUETYPE; + fd->fm->type |= F_OTF; fd->fm->type ^= F_TRUETYPE; } - } else if (is_type1(fd->fm)) - writetype1w(pdf, fd); - else - assert(0); + } else if (is_type1(fd->fm)) { + writetype1w(pdf, fd); + } else { + normal_error("fonts","there is a problem writing the font file (1)"); + } } else { - if (is_type1(fd->fm)) - writet1(pdf, fd); - else if (is_truetype(fd->fm)) + if (is_type1(fd->fm)) { + writet1(pdf, fd); + } else if (is_truetype(fd->fm)) { writettf(pdf, fd); - else if (is_opentype(fd->fm)) + } else if (is_opentype(fd->fm)) { writeotf(pdf, fd); - else - assert(0); + } else { + normal_error("fonts","there is a problem writing the font file (2)"); + } } if (!fd->ff_found) return; - assert(fd->ff_objnum == 0); fd->ff_objnum = pdf_create_obj(pdf, obj_type_others, 0); - pdf_begin_obj(pdf, fd->ff_objnum, OBJSTM_NEVER); /* font file stream */ + /*tex The font file stream: */ + pdf_begin_obj(pdf, fd->ff_objnum, OBJSTM_NEVER); pdf_begin_dict(pdf); if (is_cidkeyed(fd->fm)) { - /* No subtype is used for TrueType-based OpenType fonts */ - if (is_opentype(fd->fm) || is_type1(fd->fm)) + /*tex No subtype is used for |TRUETYPE\ based \OPENTYPE\ fonts. */ + if (is_opentype(fd->fm) || is_type1(fd->fm)) { pdf_dict_add_name(pdf, "Subtype", "CIDFontType0C"); -#if 0 - else - pdf_dict_add_name(pdf, "Subtype", "OpenType"); -#endif + } } else if (is_type1(fd->fm)) { pdf_dict_add_int(pdf, "Length1", (int) t1_length1); pdf_dict_add_int(pdf, "Length2", (int) t1_length2); @@ -478,7 +484,7 @@ static void write_fontfile(PDF pdf, fd_entry * fd) } else if (is_opentype(fd->fm)) { pdf_dict_add_name(pdf, "Subtype", "Type1C"); } else { - assert(0); /* todo: error messages */ + normal_error("fonts","there is a problem writing the font file (3)"); } pdf_dict_add_streaminfo(pdf); pdf_end_dict(pdf); @@ -488,17 +494,11 @@ static void write_fontfile(PDF pdf, fd_entry * fd) pdf_end_obj(pdf); } -@ -@c int cidset = 0; + static void write_fontdescriptor(PDF pdf, fd_entry * fd) { static const int std_flags[] = { - /* - The indices for << start with 0, but bits start with 1, so the - numbers for << are 1 lower than the bits in table 5.20. - */ - /* *INDENT-OFF* */ 1 + 2 + (1 << 5), /* Courier */ 1 + 2 + (1 << 5) + (1 << 18), /* Courier-Bold */ 1 + 2 + (1 << 5) + (1 << 6), /* Courier-Oblique */ @@ -513,31 +513,37 @@ static void write_fontdescriptor(PDF pdf, fd_entry * fd) 2 + (1 << 5) + (1 << 6), /* Times-Italic */ 2 + (1 << 5) + (1 << 6) + (1 << 18), /* Times-BoldItalic */ 4 /* ZapfDingbats */ - /* *INDENT-ON* */ }; char *glyph; struct avl_traverser t; int fd_flags; - assert(fd != NULL && fd->fm != NULL); - cidset = 0; /* possibly updated by |write_fontfile| */ + /*tex Possibly updated by |write_fontfile|: */ + cidset = 0; + if (fd->fd_objnum == 0) { + int n = 0; + int callback_id = callback_defined(font_descriptor_objnum_provider_callback); + if (callback_id) { + run_callback(callback_id, "S->d", fd->fontname, &n); + } + if (!n) { + n = pdf_create_obj(pdf, obj_type_others, 0); + } + fd->fd_objnum = n; + } if (is_fontfile(fd->fm) && is_included(fd->fm)) { - /* this will set |fd->ff_found| if font file is found */ + /*tex This will set |fd->ff_found| if font file is found: */ write_fontfile(pdf, fd); } - if (fd->fd_objnum == 0) - fd->fd_objnum = pdf_create_obj(pdf, obj_type_others, 0); pdf_begin_obj(pdf, fd->fd_objnum, OBJSTM_ALWAYS); pdf_begin_dict(pdf); pdf_dict_add_name(pdf, "Type", "FontDescriptor"); pdf_dict_add_fontname(pdf, "FontName", fd); - if (fd->fm->fd_flags != FD_FLAGS_NOT_SET_IN_MAPLINE) + if (fd->fm->fd_flags != FD_FLAGS_NOT_SET_IN_MAPLINE) { fd_flags = (int) fd->fm->fd_flags; - else if (fd->ff_found) + } else if (fd->ff_found) { fd_flags = FD_FLAGS_DEFAULT_EMBED; - else { - fd_flags = is_std_t1font(fd->fm) - ? std_flags[check_std_t1font(fd->fm->ps_name)] - : FD_FLAGS_DEFAULT_NON_EMBED; + } else { + fd_flags = is_std_t1font(fd->fm) ? std_flags[check_std_t1font(fd->fm->ps_name)] : FD_FLAGS_DEFAULT_NON_EMBED; formatted_warning("map file", "No flags specified for non-embedded font '%s' (%s), I'm using %i, fix your map entry", fd->fm->ps_name != NULL ? fd->fm->ps_name : "No name given", @@ -554,19 +560,20 @@ static void write_fontdescriptor(PDF pdf, fd_entry * fd) else if (is_opentype(fd->fm)) pdf_dict_add_ref(pdf, "FontFile3", (int) fd->ff_objnum); else - assert(0); + normal_error("fonts","there is a problem writing the font file (4)"); } else { if (is_subsetted(fd->fm) && is_type1(fd->fm)) { - /* /CharSet is optional; names may appear in any order */ - assert(fd->gl_tree != NULL); - avl_t_init(&t, fd->gl_tree); - pdf_add_name(pdf, "CharSet"); - pdf_out(pdf, '('); - for (glyph = (char *) avl_t_first(&t, fd->gl_tree); - glyph != NULL; glyph = (char *) avl_t_next(&t)) - pdf_add_name(pdf, glyph); - pdf_out(pdf, ')'); - pdf->cave = 0; + /*tex |/CharSet| is optional; names may appear in any order */ + if ((! pdf->omit_charset) && (pdf->major_version == 1)) { + avl_t_init(&t, fd->gl_tree); + pdf_add_name(pdf, "CharSet"); + pdf_out(pdf, '('); + for (glyph = (char *) avl_t_first(&t, fd->gl_tree); glyph != NULL; glyph = (char *) avl_t_next(&t)) { + pdf_add_name(pdf, glyph); + } + pdf_out(pdf, ')'); + pdf_set_space(pdf); + } } if (is_type1(fd->fm)) pdf_dict_add_ref(pdf, "FontFile", (int) fd->ff_objnum); @@ -575,16 +582,15 @@ static void write_fontdescriptor(PDF pdf, fd_entry * fd) else if (is_opentype(fd->fm)) pdf_dict_add_ref(pdf, "FontFile3", (int) fd->ff_objnum); else - assert(0); + normal_error("fonts","there is a problem writing the font file (5)"); } } if ((! pdf->omit_cidset) && (pdf->major_version == 1) && (cidset != 0) ) { pdf_dict_add_ref(pdf, "CIDSet", cidset); } - /* - Currently we don't export the optional keys for CID fonts like - \.{/Style << /Panose <12-byte string> >>} and we probably never - will. + /*tex + Currently we don't export the optional keys for CID fonts like |/Style << + /Panose <12-byte string> >>| and we probably never will. */ pdf_end_dict(pdf); pdf_end_obj(pdf); @@ -601,21 +607,13 @@ static void write_fontdescriptors(PDF pdf) write_fontdescriptor(pdf, fd); } -@ -@c static void write_fontdictionary(PDF pdf, fo_entry * fo) { - assert(fo != NULL); - assert(fo->fm != NULL); - /* reserved as |pdf_font_num(f)| elsewhere: */ - assert(fo->fo_objnum != 0); - - /* write ToUnicode entry if needed */ + /*tex Write the |/ToUnicode| entry if needed. */ if (pdf->gen_tounicode > 0 && fo->fd != NULL) { if (fo->fe != NULL) { fo->tounicode_objnum = write_tounicode(pdf, fo->fe->glyph_names, fo->fe->name); } else if (is_type1(fo->fm)) { - assert(fo->fd->builtin_glyph_names != NULL); fo->tounicode_objnum = write_tounicode(pdf, fo->fd->builtin_glyph_names, fo->fm->tfm_name); } } @@ -629,11 +627,9 @@ static void write_fontdictionary(PDF pdf, fo_entry * fo) else if (is_opentype(fo->fm)) pdf_dict_add_name(pdf, "Subtype", "Type1"); else - assert(0); - assert(fo->fd != NULL && fo->fd->fd_objnum != 0); + normal_error("fonts","there is a problem writing the font file (6)"); pdf_dict_add_fontname(pdf, "BaseFont", fo->fd); pdf_dict_add_ref(pdf, "FontDescriptor", (int) fo->fd->fd_objnum); - assert(fo->cw_objnum != 0); pdf_dict_add_int(pdf, "FirstChar", (int) fo->first_char); pdf_dict_add_int(pdf, "LastChar", (int) fo->last_char); pdf_dict_add_ref(pdf, "Widths", (int) fo->cw_objnum); @@ -642,8 +638,9 @@ static void write_fontdictionary(PDF pdf, fo_entry * fo) if (fo->tounicode_objnum != 0) pdf_dict_add_ref(pdf, "ToUnicode", (int) fo->tounicode_objnum); if (pdf_font_attr(fo->tex_font) != get_nullstr() && pdf_font_attr(fo->tex_font) != 0) { + pdf_check_space(pdf); pdf_print(pdf, pdf_font_attr(fo->tex_font)); - pdf_out(pdf, '\n'); + pdf_set_space(pdf); } pdf_end_dict(pdf); pdf_end_obj(pdf); @@ -656,49 +653,53 @@ static void write_fontdictionaries(PDF pdf) if (fo_tree == NULL) return; avl_t_init(&t, fo_tree); - for (fo = (fo_entry *) avl_t_first(&t, fo_tree); fo != NULL; fo = (fo_entry *) avl_t_next(&t)) + for (fo = (fo_entry *) avl_t_first(&t, fo_tree); fo != NULL; fo = (fo_entry *) avl_t_next(&t)) { write_fontdictionary(pdf, fo); + } } -@ Final flush of all font related stuff by call from \.{Output fonts -definitions} elsewhere -@c +/*tex + + Final flush of all font related stuff by call from \.{Output fonts + definitions} elsewhere. + +*/ + void write_fontstuff(PDF pdf) { write_fontdescriptors(pdf); - write_fontencodings(pdf); /* see \.{writeenc.w} */ + write_fontencodings(pdf); write_fontdictionaries(pdf); } -@ -@c static void create_fontdictionary(PDF pdf, internal_font_number f) { fo_entry *fo = new_fo_entry(); fm_entry *fm = font_map(f); - /* set |fo->first_char| and |fo->last_char| from |f| */ + /*tex set |fo->first_char| and |fo->last_char| from |f| */ get_char_range(fo, f); if (fo->last_char > 255) fo->last_char = 255; - assert(fo->last_char >= fo->first_char); fo->fm = fm; fo->fo_objnum = pdf_font_num(f); fo->tex_font = f; if (is_reencoded(fo->fm)) { - /* + /*tex At least the map entry tells so but it returns |NULL| if the .enc file couldn't be opened. */ fo->fe = get_fe_entry(fo->fm->encname); if (fo->fe != NULL && (is_type1(fo->fm) || is_opentype(fo->fm))) { - /* We don't end up here for truetype fonts. */ - if (fo->fe->fe_objnum == 0) - fo->fe->fe_objnum = pdf_create_obj(pdf, obj_type_others, 0); /* then it will be written out */ - /* Mark encoding pairs used by TeX to optimize encoding vector. */ + /*tex We don't end up here for truetype fonts. */ + if (fo->fe->fe_objnum == 0) { + /*tex It will be written out */ + fo->fe->fe_objnum = pdf_create_obj(pdf, obj_type_others, 0); + } + /*tex Mark encoding pairs used by TeX to optimize encoding vector. */ fo->fe->tx_tree = mark_chars(fo, fo->fe->tx_tree, f); } } - /* for |write_charwidth_array|: */ + /*tex For |write_charwidth_array|: */ fo->tx_tree = mark_chars(fo, fo->tx_tree, f); write_charwidth_array(pdf, fo, f); if (!is_builtin(fo->fm)) { @@ -713,7 +714,7 @@ static void create_fontdictionary(PDF pdf, internal_font_number f) if (fo->fe != NULL) { mark_reenc_glyphs(fo, f); if (!is_type1(fo->fm)) { - /* mark reencoded characters as chars on TeX level */ + /*tex Mark reencoded characters as chars on TeX level. */ assert(fo->fd->tx_tree == NULL); fo->fd->tx_tree = mark_chars(fo, fo->fd->tx_tree, f); if (is_truetype(fo->fm)) { @@ -721,16 +722,17 @@ static void create_fontdictionary(PDF pdf, internal_font_number f) } } } else { - /* mark non-reencoded characters as chars on TeX level */ + /*tex Mark non-reencoded characters as chars on TeX level. */ fo->fd->tx_tree = mark_chars(fo, fo->fd->tx_tree, f); } if (!is_type1(fo->fm)) { write_fontdescriptor(pdf, fo->fd); } } else { - /* - Builtin fonts still need the /Widths array and /FontDescriptor - (to avoid error 'font FOO contains bad /BBox'). + /*tex + Builtin fonts still need the \type {/Widths} array and \type + {/FontDescriptor} (to avoid error \quotation {font FOO contains bad + \type {/BBox}}). */ create_fontdescriptor(fo, f); write_fontdescriptor(pdf, fo->fd); @@ -745,8 +747,6 @@ static void create_fontdictionary(PDF pdf, internal_font_number f) } } -@ -@c static int has_ttf_outlines(fm_entry * fm) { FILE *f = fopen(fm->ff_name, "rb"); @@ -767,38 +767,39 @@ void do_pdf_font(PDF pdf, internal_font_number f) { int del_file = 0; fm_entry *fm; - /* - This is not 100\% true: CID is actually needed whenever (and - only) there are more than 256 separate glyphs used. But for - now, we just assume the user knows what he is doing. In practice - this seems to be the case. + /*tex + This is not 100\% true: CID is actually needed whenever (and only) there + are more than 256 separate glyphs used. But for now, we just assume the + user knows what he is doing. In practice this seems to be the case. */ if (!font_has_subset(f)) return; - if (font_encodingbytes(f) == 2) { - /* - Create a virtual font map entry, as this is needed by the - rest of the font inclusion mechanism. + /*tex + Create a virtual font map entry, as this is needed by the rest of the + font inclusion mechanism. */ fm = font_map(f) = new_fm_entry(); - fm->tfm_name = font_name(f); /* or whatever, not a real tfm */ - fm->ff_name = font_filename(f); /* the actual file */ - if (font_psname(f) != NULL) - fm->ps_name = font_psname(f); /* the true name */ - else - fm->ps_name = font_fullname(f); /* the true name */ + /*tex Set this to a name or whatever, not a real \TFM\ anyway: */ + fm->tfm_name = font_name(f); + /*tex The actual file: */ + fm->ff_name = font_filename(f); + /*tex The true (used) name: */ + if (font_psname(f) != NULL) { + fm->ps_name = font_psname(f); + } else { + fm->ps_name = font_fullname(f); + } if (fm->ff_name && strlen(fm->ff_name) >= 6 && strstr(fm->ff_name,".dfont") == (fm->ff_name + strlen(fm->ff_name) - 6)) { - /* - In case of a .dfont, we will extract the correct ttf here, - and adjust |fm->ff_name| to point to the temporary file. - This file will be deleted later. Todo: keep a nicer name - somewhere for the terminal message. - - Support for dfonts will be removed at some point anyhow. - */ + /*tex + + In case of a .dfont (an obsolete format), we will extract the + correct ttf here, and adjust |fm->ff_name| to point to the + temporary file. This file will be deleted later. Todo: keep a + nicer name somewhere for the terminal message. + */ char *s = FindResourceTtfFont(fm->ff_name, fm->ps_name); if (s != NULL) { fm->ff_name = s; @@ -807,35 +808,34 @@ void do_pdf_font(PDF pdf, internal_font_number f) formatted_error("font","file '%s' does not contain font '%s'",fm->ff_name, fm->ps_name); } } - /* Needed for the CIDSystemInfo: */ + /*tex Needed for the CIDSystemInfo: */ fm->encname = font_encodingname(f); fm->slant = font_slant(f); set_slantset(fm); fm->extend = font_extend(f); set_extendset(fm); - /* Flags can perhaps be done better. */ + /*tex Flags can perhaps be done better. */ fm->fd_flags = 4; set_inuse(fm); - switch (font_format(f)) { - case opentype_format: - if (has_ttf_outlines(fm)) { + case opentype_format: + if (has_ttf_outlines(fm)) { + set_truetype(fm); + } else { + set_opentype(fm); + } + break; + case truetype_format: set_truetype(fm); - } else { - set_opentype(fm); - } - break; - case truetype_format: - set_truetype(fm); - break; - case type1_format: - set_type1(fm); - break; - default: - formatted_error("font","file format '%s' for '%s' is incompatible with wide characters", - font_format_name(f), font_name(f)); + break; + case type1_format: + set_type1(fm); + break; + default: + formatted_error("font","file format '%s' for '%s' is incompatible with wide characters", + font_format_name(f), font_name(f)); } - /* This makes "unknown" default to subsetted inclusion */ + /*tex This makes \quotation {unknown} default to subsetted inclusion. */ if (font_embedding(f) != no_embedding) { set_included(fm); if (font_embedding(f) != full_embedding) { @@ -844,37 +844,33 @@ void do_pdf_font(PDF pdf, internal_font_number f) } set_cidkeyed(fm); create_cid_fontdictionary(pdf, f); - if (del_file) unlink(fm->ff_name); - } else { - /* - By now |font_map(f)|, if any, should have been set via - |pdf_init_font()|. - */ - if ((fm = font_map(f)) == NULL - || (fm->ps_name == NULL && fm->ff_name == NULL)) + /*tex By now |font_map(f)|, if any, should have been set via |pdf_init_font|. */ + if ((fm = font_map(f)) == NULL || (fm->ps_name == NULL && fm->ff_name == NULL)) writet3(pdf, f); else create_fontdictionary(pdf, f); } } -@ The glyph width is included in |glw_entry|, because that width -depends on the value it has in the font where it is actually -typeset from, not the font that is the 'owner' of the fd entry. +/*tex + + The glyph width is included in |glw_entry|, because that width depends on the + value it has in the font where it is actually typeset from, not the font that + is the owner of the fd entry. -TODO: It is possible that the user messes with the metric width, -but handling that properly would require access to the 'hmtx' table -at this point in the program. + It is possible that the user messes with the metric width, but handling that + properly would require access to the |hmtx| table at this point in the + program. + +*/ -@c static int comp_glw_entry(const void *pa, const void *pb, void *p - __attribute__ ((unused))) + __attribute__ ((unused))) { unsigned short i, j; - i = (unsigned short) (*(const glw_entry *) pa).id; j = (unsigned short) (*(const glw_entry *) pb).id; cmp_return(i, j); @@ -883,59 +879,24 @@ static int comp_glw_entry(const void *pa, const void *pb, void *p static void create_cid_fontdescriptor(fo_entry * fo, internal_font_number f) { - assert(fo != NULL); - assert(fo->fm != NULL); - assert(fo->fd == NULL); fo->fd = new_fd_entry(f); preset_fontname(fo, f); preset_fontmetrics(fo->fd, f); - fo->fd->fe = fo->fe; /* encoding needed by TrueType writing */ - fo->fd->fm = fo->fm; /* map entry needed by TrueType writing */ + /*tex Encoding needed by \TRUETYPE\ writing: */ + fo->fd->fe = fo->fe; + /*tex Map entry needed by \TRUETYPE\ writing */ + fo->fd->fm = fo->fm; fo->fd->gl_tree = avl_create(comp_glw_entry, NULL, &avl_xallocator); assert(fo->fd->gl_tree != NULL); } -@ The values |font_bc()| and |font_ec()| are potentially large character -ids, but the strings that are written out use CID indexes, and those are -limited to 16-bit values. +/*tex -@c -/* - This is old code ... it fails when the order of using the same font at - different extends changes. Probably because widths get overwritten or - set wrong. The loop also looks kind of weird (why a loop). -*/ + The values |font_bc()| and |font_ec()| are potentially large character ids, + but the strings that are written out use CID indexes, and those are limited + to 16-bit values. -/* -static void mark_cid_subset_glyphs(fo_entry * fo, internal_font_number f) -{ - int i, k, l; - glw_entry *j; - void *aa; - for (k = 1; k <= max_font_id(); k++) { - if (k == f || -f == pdf_font_num(k)) { - l = font_size(k); - for (i = font_bc(k); i <= font_ec(k); i++) { - if (quick_char_exists(k, i) && char_used(k, i)) { - j = xtalloc(1, glw_entry); - j->id = (unsigned) char_index(k, i); - j->wd = divide_scaled_n(char_width(k, i), l, 10000.0); - if ((glw_entry *) avl_find(fo->fd->gl_tree, j) == NULL) { - aa = avl_probe(fo->fd->gl_tree, j); - assert(aa != NULL); - } else { - xfree(j); - } - } - } - } - } -} -*/ - -/* - So, let's try the following. */ static void mark_cid_subset_glyphs(fo_entry * fo, internal_font_number f) @@ -951,7 +912,9 @@ static void mark_cid_subset_glyphs(fo_entry * fo, internal_font_number f) j->wd = divide_scaled_n(char_width(f, i), l, 10000.0); if ((glw_entry *) avl_find(fo->fd->gl_tree, j) == NULL) { aa = avl_probe(fo->fd->gl_tree, j); - assert(aa != NULL); + if (aa == NULL) { + /*tex Is this a problem? */ + } } else { xfree(j); } @@ -959,30 +922,29 @@ static void mark_cid_subset_glyphs(fo_entry * fo, internal_font_number f) } } -@ It is possible to compress the widths array even better, by using the -alternate 'range' syntax and possibly even using /DW to set a default -value. +/*tex + + It is possible to compress the widths array even better, by using the + alternate 'range' syntax and possibly even using /DW to set a default value. + + There is a some optimization here already: glyphs that are not used do not + appear in the widths array at all. -There is a some optimization here already: glyphs that are not used do -not appear in the widths array at all. + We have to make sure that we do not output an (incorrect!) width for a + character that exists in the font, but is not used in typesetting. An + enormous negative width is used as sentinel value -We have to make sure that we do not output an (incorrect!) width for a -character that exists in the font, but is not used in typesetting. An -enormous negative width is used as sentinel value +*/ -@c static void write_cid_charwidth_array(PDF pdf, fo_entry * fo) { int i, j; glw_entry *glyph; struct avl_traverser t; - - assert(fo->cw_objnum == 0); fo->cw_objnum = pdf_create_obj(pdf, obj_type_others, 0); pdf_begin_obj(pdf, fo->cw_objnum, OBJSTM_ALWAYS); avl_t_init(&t, fo->fd->gl_tree); glyph = (glw_entry *) avl_t_first(&t, fo->fd->gl_tree); - assert(glyph != NULL); i = (int) glyph->id; pdf_begin_array(pdf); pdf_add_int(pdf, i); @@ -995,19 +957,16 @@ static void write_cid_charwidth_array(PDF pdf, fo_entry * fo) pdf_begin_array(pdf); j = glyph->wd; } - if (glyph->id == (unsigned) (i + 1)) - pdf_out(pdf, ' '); - + pdf_check_space(pdf); if (j < 0) { pdf_out(pdf, '-'); j = -j; } - pdf_printf(pdf, "%i", (j / 10)); if ((j % 10) != 0) pdf_printf(pdf, ".%i", (j % 10)); - i = (int) glyph->id; + pdf_set_space(pdf); } pdf_end_array(pdf); pdf_end_array(pdf); @@ -1026,15 +985,15 @@ static void create_cid_fontdictionary(PDF pdf, internal_font_number f) { fm_entry *fm = font_map(f); fo_entry *fo = new_fo_entry(); - get_char_range(fo, f); /* set |fo->first_char| and |fo->last_char| from |f| */ - assert(fo->last_char >= fo->first_char); + /*tex set |fo->first_char| and |fo->last_char| from |f| */ + get_char_range(fo, f); fo->fm = fm; fo->fo_objnum = pdf_font_num(f); fo->tex_font = f; create_cid_fontdescriptor(fo, f); mark_cid_subset_glyphs(fo, f); if (is_subsetted(fo->fm)) { - /* + /*tex This is a bit sneaky. |make_subset_tag()| actually expects the glyph tree to contain strings instead of |glw_entry| items. However, all calculations are done using explicit typecasts, so it works out ok. @@ -1043,24 +1002,20 @@ static void create_cid_fontdictionary(PDF pdf, internal_font_number f) } write_cid_charwidth_array(pdf, fo); write_fontdescriptor(pdf, fo->fd); - write_cid_fontdictionary(pdf, fo, f); if (fo->fd) { - if (fo->fd->gl_tree){ - avl_destroy(fo->fd->gl_tree,destroy_glw_cid_entry); - } - xfree(fo->fd); + if (fo->fd->gl_tree) { + avl_destroy(fo->fd->gl_tree,destroy_glw_cid_entry); + } + xfree(fo->fd); } xfree(fo); } -@ @c void write_cid_fontdictionary(PDF pdf, fo_entry * fo, internal_font_number f) { int i; - fo->tounicode_objnum = write_cid_tounicode(pdf, fo, f); - pdf_begin_obj(pdf, fo->fo_objnum, OBJSTM_ALWAYS); pdf_begin_dict(pdf); pdf_dict_add_name(pdf, "Type", "Font"); @@ -1076,12 +1031,10 @@ void write_cid_fontdictionary(PDF pdf, fo_entry * fo, internal_font_number f) pdf_begin_array(pdf); pdf_add_ref(pdf, i); pdf_end_array(pdf); - /* todo: the ToUnicode CMap */ if (fo->tounicode_objnum != 0) pdf_dict_add_ref(pdf, "ToUnicode", (int) fo->tounicode_objnum); pdf_end_dict(pdf); pdf_end_obj(pdf); - pdf_begin_obj(pdf, i, OBJSTM_ALWAYS); pdf_begin_dict(pdf); pdf_dict_add_name(pdf, "Type", "Font"); @@ -1100,17 +1053,17 @@ void write_cid_fontdictionary(PDF pdf, fo_entry * fo, internal_font_number f) pdf_dict_add_string(pdf, "Ordering", (font_cidordering(f) ? font_cidordering(f) : "Identity")); pdf_dict_add_int(pdf, "Supplement", (int) font_cidsupplement(f)); pdf_end_dict(pdf); - - /* I doubt there is anything useful that could be written here */ - -#if 0 - if (pdf_font_attr(fo->tex_font) != get_nullstr()) { - pdf_out(pdf, '\n'); - pdf_print(pdf_font_attr(fo->tex_font)); - pdf_out(pdf, '\n'); - } -#endif - + /*tex + I doubt there is anything useful that could be written here so for now we + comment this. + */ + /* + if (pdf_font_attr(fo->tex_font) != get_nullstr()) { + pdf_out(pdf, '\n'); + pdf_print(pdf_font_attr(fo->tex_font)); + pdf_out(pdf, '\n'); + } + */ pdf_end_dict(pdf); pdf_end_obj(pdf); } diff --git a/Build/source/texk/web2c/luatexdir/font/writet1.w b/Build/source/texk/web2c/luatexdir/font/writet1.c index fc1a89cd547..0a0cadcfb93 100644 --- a/Build/source/texk/web2c/luatexdir/font/writet1.w +++ b/Build/source/texk/web2c/luatexdir/font/writet1.c @@ -1,44 +1,40 @@ -% writet1.w -% -% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org> -% Copyright 2006-2009 Taco Hoekwater <taco@@luatex.org> -% -% This file is part of LuaTeX. -% -% LuaTeX 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. -% -% LuaTeX 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 Lesser General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License along -% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. - -@ @c +/* +Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> +Copyright 2006-2009 Taco Hoekwater <taco@luatex.org> -#include "ptexlib.h" -#include <string.h> +This file is part of LuaTeX. + +LuaTeX 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. -#define get_length1() t1_length1 = t1_offset() - t1_save_offset -#define get_length2() t1_length2 = t1_offset() - t1_save_offset -#define get_length3() t1_length3 = fixedcontent? t1_offset() - t1_save_offset : 0 -#define save_offset() t1_save_offset = t1_offset() +LuaTeX 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 Lesser General Public +License for more details. -#define t1_putchar(A) strbuf_putchar(pdf->fb, (A)) -#define t1_offset() strbuf_offset(pdf->fb) -#define out_eexec_char t1_putchar +You should have received a copy of the GNU General Public License along +with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +*/ + +#include "ptexlib.h" +#include <string.h> -#define end_last_eexec_line() \ - t1_eexec_encrypt = false -#define t1_char(c) c -#define embed_all_glyphs(tex_font) fm_cur->all_glyphs -#define extra_charset() fm_cur->charset -#define fixedcontent false +#define get_length1() t1_length1 = t1_offset() - t1_save_offset +#define get_length2() t1_length2 = t1_offset() - t1_save_offset +#define get_length3() t1_length3 = fixedcontent? t1_offset() - t1_save_offset : 0 +#define save_offset() t1_save_offset = t1_offset() +#define t1_putchar(A) strbuf_putchar(pdf->fb, (A)) +#define t1_offset() strbuf_offset(pdf->fb) +#define out_eexec_char t1_putchar +#define end_last_eexec_line() t1_eexec_encrypt = false +#define t1_char(c) c +#define embed_all_glyphs(tex_font) fm_cur->all_glyphs +#define extra_charset() fm_cur->charset +#define fixedcontent false int t1_length1, t1_length2, t1_length3; static int t1_save_offset; @@ -47,40 +43,35 @@ static int t1_fontname_offset; static unsigned char *t1_buffer = NULL; static int t1_size = 0; static int t1_curbyte = 0; -@ @c -#define t1_read_file() \ - readbinfile(t1_file,&t1_buffer,&t1_size) -#define t1_close() xfclose(t1_file,cur_file_name) -#define t1_getchar() t1_buffer[t1_curbyte++] -#define t1_ungetchar(c) t1_curbyte-- -#define t1_eof() (t1_curbyte>t1_size) - -#define t1_prefix(s) str_prefix(t1_line_array, s) -#define t1_buf_prefix(s) str_prefix(t1_buf_array, s) -#define t1_suffix(s) str_suffix(t1_line_array, t1_line_ptr, s) -#define t1_buf_suffix(s) str_suffix(t1_buf_array, t1_buf_ptr, s) -#define t1_charstrings() strstr(t1_line_array, charstringname) -#define t1_subrs() t1_prefix("/Subrs") -#define t1_end_eexec() t1_suffix("mark currentfile closefile") -#define t1_cleartomark() t1_prefix("cleartomark") + +#define t1_read_file() readbinfile(t1_file,&t1_buffer,&t1_size) +#define t1_close() xfclose(t1_file,cur_file_name) +#define t1_getchar() t1_buffer[t1_curbyte++] +#define t1_ungetchar(c) t1_curbyte-- +#define t1_eof() (t1_curbyte>t1_size) + +#define t1_prefix(s) str_prefix(t1_line_array, s) +#define t1_buf_prefix(s) str_prefix(t1_buf_array, s) +#define t1_suffix(s) str_suffix(t1_line_array, t1_line_ptr, s) +#define t1_buf_suffix(s) str_suffix(t1_buf_array, t1_buf_ptr, s) +#define t1_charstrings() strstr(t1_line_array, charstringname) +#define t1_subrs() t1_prefix("/Subrs") +#define t1_end_eexec() t1_suffix("mark currentfile closefile") +#define t1_cleartomark() t1_prefix("cleartomark") static unsigned char *enc_buffer = NULL; static int enc_size = 0; static int enc_curbyte = 0; -@ @c -#define enc_open(a) \ - (enc_file = fopen((char *)(a), FOPEN_RBIN_MODE)) -#define enc_read_file() \ - readbinfile(enc_file,&enc_buffer,&enc_size) -#define enc_close() xfclose(enc_file,cur_file_name) -#define enc_getchar() enc_buffer[enc_curbyte++] -#define enc_eof() (enc_curbyte>enc_size) +#define enc_open(a) (enc_file = fopen((char *)(a), FOPEN_RBIN_MODE)) +#define enc_read_file() readbinfile(enc_file,&enc_buffer,&enc_size) +#define enc_close() xfclose(enc_file,cur_file_name) +#define enc_getchar() enc_buffer[enc_curbyte++] +#define enc_eof() (enc_curbyte>enc_size) -#define valid_code(c) (c >= 0 && c < 256) -#define fixedcontent false +#define valid_code(c) (c >= 0 && c < 256) +#define fixedcontent false -@ @c static const char *standard_glyph_names[256] = { /* 0x00 */ notdef, notdef, notdef, notdef, notdef, notdef, notdef, notdef, notdef, @@ -138,25 +129,23 @@ static const char *standard_glyph_names[256] = { "oslash", "oe", "germandbls", notdef, notdef, notdef, notdef }; -@ @c static fd_entry *fd_cur; static char charstringname[] = "/CharStrings"; enum { ENC_STANDARD, ENC_BUILTIN } t1_encoding; -#define T1_BUF_SIZE 0x10 +#define T1_BUF_SIZE 0x0010 #define ENC_BUF_SIZE 0x1000 -@ @c -#define CS_HSTEM 1 -#define CS_VSTEM 3 -#define CS_VMOVETO 4 -#define CS_RLINETO 5 -#define CS_HLINETO 6 -#define CS_VLINETO 7 -#define CS_RRCURVETO 8 -#define CS_CLOSEPATH 9 +#define CS_HSTEM 1 +#define CS_VSTEM 3 +#define CS_VMOVETO 4 +#define CS_RLINETO 5 +#define CS_HLINETO 6 +#define CS_VLINETO 7 +#define CS_RRCURVETO 8 +#define CS_CLOSEPATH 9 #define CS_CALLSUBR 10 #define CS_RETURN 11 #define CS_ESCAPE 12 @@ -168,11 +157,11 @@ enum { ENC_STANDARD, ENC_BUILTIN } t1_encoding; #define CS_HVCURVETO 31 #define CS_1BYTE_MAX (CS_HVCURVETO + 1) -#define CS_DOTSECTION CS_1BYTE_MAX + 0 -#define CS_VSTEM3 CS_1BYTE_MAX + 1 -#define CS_HSTEM3 CS_1BYTE_MAX + 2 -#define CS_SEAC CS_1BYTE_MAX + 6 -#define CS_SBW CS_1BYTE_MAX + 7 +#define CS_DOTSECTION CS_1BYTE_MAX + 0 +#define CS_VSTEM3 CS_1BYTE_MAX + 1 +#define CS_HSTEM3 CS_1BYTE_MAX + 2 +#define CS_SEAC CS_1BYTE_MAX + 6 +#define CS_SBW CS_1BYTE_MAX + 7 #define CS_DIV CS_1BYTE_MAX + 12 #define CS_CALLOTHERSUBR CS_1BYTE_MAX + 16 #define CS_POP CS_1BYTE_MAX + 17 @@ -180,21 +169,28 @@ enum { ENC_STANDARD, ENC_BUILTIN } t1_encoding; #define CS_2BYTE_MAX (CS_SETCURRENTPOINT + 1) #define CS_MAX CS_2BYTE_MAX -@ @c typedef unsigned char byte; +/*tex A |CharString| command: */ + typedef struct { - byte nargs; /* number of arguments */ - boolean bottom; /* take arguments from bottom of stack? */ - boolean clear; /* clear stack? */ + /*tex number of arguments */ + byte nargs; + /*tex take arguments from bottom of stack? */ + boolean bottom; + /*tex clear stack? */ + boolean clear; boolean valid; -} cc_entry; /* CharString Command */ +} cc_entry; typedef struct { - char *name; /* glyph name (or notdef for Subrs entry) */ + /*tex glyph name (or |notdef| for |Subrs| entry) */ + char *name; byte *data; - unsigned short len; /* length of the whole string */ - unsigned short cslen; /* length of the encoded part of the string */ + /*tex length of the whole string */ + unsigned short len; + /*tex length of the encoded part of the string */ + unsigned short cslen; boolean used; boolean valid; } cs_entry; @@ -205,13 +201,9 @@ static unsigned short t1_cslen; static short t1_lenIV; static char enc_line[ENC_BUF_SIZE]; -@ define |t1_line_ptr|, |t1_line_array|, and |t1_line_limit| -@c #define t1_line_entry char define_array(t1_line); -@ define |t1_buf_ptr|, |t1_buf_array|, and |t1_buf_limit| -@c #define t1_buf_entry char define_array(t1_buf); @@ -225,29 +217,34 @@ static cs_entry *subr_tab; static char *subr_array_start, *subr_array_end; static int subr_max, subr_size, subr_size_pos; -@ This list contains the begin/end tokens commonly used in the -/Subrs array of a Type 1 font. +/*tex + + This list contains the begin/end tokens commonly used in the |/Subrs| array of + a Type 1 font. + +*/ -@c static const char *cs_token_pairs_list[][2] = { - {" RD", "NP"}, - {" -|", "|"}, - {" RD", "noaccess put"}, - {" -|", "noaccess put"}, - {NULL, NULL} + { " RD", "NP" }, + { " -|", "|" }, + { " RD", "noaccess put" }, + { " -|", "noaccess put" }, + { NULL, NULL } }; -@ @c static const char **cs_token_pair; static boolean t1_pfa, t1_cs, t1_scan, t1_eexec_encrypt, t1_synthetic; -static int t1_in_eexec; /* 0 before eexec-encrypted, 1 during, 2 after */ + +/*tex This one becomes 0 before 1 during and 2 after |eexec| encryption. */ + +static int t1_in_eexec; + static long t1_block_length; static int last_hexbyte; static FILE *t1_file; static FILE *enc_file; -@ @c static void enc_getline(void) { char *p; @@ -266,19 +263,20 @@ static void enc_getline(void) goto restart; } -@ read encoding from .enc file, return |glyph_names array|, or |pdffail()| -@c +/*tex + + Read encoding from .enc file, return |glyph_names array|, or |pdffail|. + +*/ + char **load_enc_file(char *enc_name) { int callback_id = 0; int file_opened = 0; - char buf[ENC_BUF_SIZE], *p, *r; int i, names_count; char **glyph_names; - cur_file_name = luatex_find_file(enc_name, find_enc_file_callback); - if (cur_file_name == NULL) { formatted_error("type 1","cannot find encoding file '%s' for reading", enc_name); } @@ -308,7 +306,8 @@ char **load_enc_file(char *enc_name) formatted_error("type 1","invalid encoding vector (a name or '[' missing): '%s'", enc_line); } names_count = 0; - r++; /* skip '[' */ + /*tex Skip |[|: */ + r++; skip_char(r, ' '); for (;;) { while (*r == '/') { @@ -340,19 +339,6 @@ char **load_enc_file(char *enc_name) return glyph_names; } -@ @c -#if 0 -static void free_glyph_names(char **glyph_names) -{ - int i; - assert(glyph_names != NULL); - for (i = 0; i < 256; i++) - if (glyph_names[i] != notdef) - xfree(glyph_names[i]); - xfree(glyph_names); -} -#endif - static void t1_check_pfa(void) { const int c = t1_getchar(); @@ -402,8 +388,7 @@ static byte edecrypt(byte cipher) if (t1_pfa) { while (cipher == 10 || cipher == 13) cipher = (byte) t1_getbyte(); - last_hexbyte = cipher = - (byte) ((hexval(cipher) << 4) + hexval(t1_getbyte())); + last_hexbyte = cipher = (byte) ((hexval(cipher) << 4) + hexval(t1_getbyte())); } plain = (byte) (cipher ^ (t1_dr >> 8)); t1_dr = (unsigned short) ((cipher + t1_dr) * t1_c1 + t1_c2); @@ -457,8 +442,7 @@ static float t1_scan_num(char *p, char **r) return f; } -static boolean str_suffix(const char *begin_buf, const char *end_buf, - const char *s) +static boolean str_suffix(const char *begin_buf, const char *end_buf, const char *s) { const char *s1 = end_buf - 1, *s2 = strend(s) - 1; if (*s1 == 10) @@ -470,13 +454,12 @@ static boolean str_suffix(const char *begin_buf, const char *end_buf, return s2 < s; } -@ @c static void t1_getline(void) { int c, l, eexec_scan; char *p; static const char eexec_str[] = "currentfile eexec"; - static int eexec_len = 17; /* |strlen(eexec_str)| */ + static int eexec_len = 17; restart: if (t1_eof()) normal_error("type 1","unexpected end of file"); @@ -512,26 +495,27 @@ static void t1_getline(void) p--; l = (int) t1_scan_num(p + 1, 0); t1_cslen = (unsigned short) l; - cs_start = (int) (t1_line_ptr - t1_line_array); /* |cs_start| is an index now */ + /*tex |cs_start| is an index now */ + cs_start = (int) (t1_line_ptr - t1_line_array); alloc_array(t1_line, l, T1_BUF_SIZE); while (l-- > 0) *t1_line_ptr++ = (t1_line_entry) edecrypt((byte) t1_getbyte()); } c = t1_getbyte(); } - alloc_array(t1_line, 2, T1_BUF_SIZE); /* |append_eol| can append 2 chars */ + /*tex |append_eol| can append 2 chars */ + alloc_array(t1_line, 2, T1_BUF_SIZE); append_eol(t1_line_ptr, t1_line_array, t1_line_limit); if (t1_line_ptr - t1_line_array < 2) goto restart; if (eexec_scan == eexec_len) t1_in_eexec = 1; exit: - /* ensure that |t1_buf_array| has as much room as |t1_line_array| */ + /*tex Ensure that |t1_buf_array| has as much room as |t1_line_array|. */ t1_buf_ptr = t1_buf_array; alloc_array(t1_buf, t1_line_limit, t1_line_limit); } -@ @c static void t1_putline(PDF pdf) { char *p = t1_line_array; @@ -563,7 +547,6 @@ static void t1_printf(PDF pdf, const char *fmt, ...) va_end(args); } -@ @c static void t1_init_params(int open_name_prefix) { report_start_file(open_name_prefix,cur_file_name); @@ -599,14 +582,11 @@ static void t1_check_block_len(boolean decrypt) } } -@ @c static void t1_start_eexec(PDF pdf) { int i; - assert(is_included(fd_cur->fm)); get_length1(); save_offset(); - if (!t1_pfa) t1_check_block_len(false); for (t1_line_ptr = t1_line_array, i = 0; i < 4; i++) { @@ -614,13 +594,13 @@ static void t1_start_eexec(PDF pdf) *t1_line_ptr++ = 0; } t1_eexec_encrypt = true; - t1_putline(pdf); /* to put the first four bytes */ + /*tex To put the first four bytes: */ + t1_putline(pdf); } static void t1_stop_eexec(PDF pdf) { int c; - assert(is_included(fd_cur->fm)); get_length2(); save_offset(); t1_eexec_encrypt = false; @@ -639,9 +619,8 @@ static void t1_stop_eexec(PDF pdf) t1_in_eexec = 2; } -@ macros for various transforms; unused, left for reference +/*tex Macros for various transforms; unused, left for reference: */ -@c #ifdef T1TRANSFORMMACROS # define do_xshift(x,a) {x[4]+=a;} # define do_yshift(x,a) {x[5]+=a;} @@ -651,17 +630,18 @@ static void t1_stop_eexec(PDF pdf) # define do_scale(x,a) {do_xscale(x,a); do_yscale(x,a);} # define do_slant(x,a) {x[0]+=x[1]*(a); x[2]+=x[3]*(a); x[4]+=x[5]*(a);} # define do_shear(x,a) {x[1]+=x[0]*(a); x[3]+=x[2]*(a); x[5]+=x[4]*(a);} -# define do_rotate(x,a) \ - {float t, u=cos(a), v=sin(a); \ - t =x[0]*u+x[1]*-v; \ - x[1] =x[0]*v+x[1]* u; x[0]=t; \ - t =x[2]*u+x[3]*-v; \ - x[3] =x[2]*v+x[3]* u; x[2]=t; \ - t =x[4]*u+x[5]*-v; \ - x[5] =x[4]*v+x[5]* u; x[4]=t;} + +# define do_rotate(x,a) { \ + float t, u=cos(a), v=sin(a); \ + t =x[0]*u+x[1]*-v; \ + x[1] =x[0]*v+x[1]* u; x[0]=t; \ + t =x[2]*u+x[3]*-v; \ + x[3] =x[2]*v+x[3]* u; x[2]=t; \ + t =x[4]*u+x[5]*-v; \ + x[5] =x[4]*v+x[5]* u; x[4]=t; \ +} #endif -@ @c static void t1_scan_keys(PDF pdf) { int i, k; @@ -688,16 +668,20 @@ static void t1_scan_keys(PDF pdf) remove_eol(p, t1_line_array); formatted_error("type 1","a name expected: '%s'", t1_line_array); } - r = ++p; /* skip the slash */ + /*tex Skip the slash. */ + r = ++p; for (q = t1_buf_array; *p != ' ' && *p != 10; *q++ = *p++); *q = 0; xfree(fd_cur->fontname); fd_cur->fontname = xstrdup(t1_buf_array); - /* at this moment we cannot call |make_subset_tag()| yet, as the encoding - is not read; thus we mark the offset of the subset tag and write it - later */ + /*tex + + At this moment we cannot call |make_subset_tag| yet, as the encoding + is not read; thus we mark the offset of the subset tag and write it + later. + + */ if (is_subsetted(fd_cur->fm)) { - assert(is_included(fd_cur->fm)); t1_fontname_offset = (int) (t1_offset() + (r - t1_line_array)); strcpy(t1_buf_array, p); sprintf(r, "ABCDEF+%s%s", fd_cur->fontname, t1_buf_array); @@ -719,7 +703,6 @@ static void t1_scan_keys(PDF pdf) fd_cur->font_dim[k].set = true; } -@ @c static void t1_scan_param(PDF pdf) { static const char *lenIV = "/lenIV"; @@ -745,18 +728,18 @@ static void copy_glyph_names(char **glyph_names, int a, int b) } } -@ read encoding from Type1 font file, return |glyph_names| array, or |pdffail()| +/*tex Read encoding from Type1 font file, return |glyph_names| array, or |pdffail|. */ -@c static char **t1_builtin_enc(void) { int i, a, b, c, counter = 0; char *r, *p, **glyph_names; - /* At this moment \.{/Encoding} is the prefix of |t1_line_array| */ + /*tex At this moment |/Encoding| is the prefix of |t1_line_array|. */ glyph_names = xtalloc(256, char *); for (i = 0; i < 256; i++) glyph_names[i] = (char *) notdef; - if (t1_suffix("def")) { /* predefined encoding */ + if (t1_suffix("def")) { + /*tex A predefined encoding: */ sscanf(t1_line_array + strlen("/Encoding"), "%255s", t1_buf_array); if (strcmp(t1_buf_array, "StandardEncoding") == 0) { t1_encoding = ENC_STANDARD; @@ -768,31 +751,37 @@ static char **t1_builtin_enc(void) } else formatted_error("type 1","cannot subset font (unknown predefined encoding '%s')",t1_buf_array); } - /* At this moment \.{/Encoding} is the prefix of |t1_line_array|, and the encoding is - not a predefined encoding. - - We have two possible forms of Encoding vector. The first case is - - \.{/Encoding [/a /b /c...] readonly def} - - and the second case can look like - - {\obeylines - \.{/Encoding 256 array 0 1 255 {1 index exch /.notdef put} for} - \.{dup 0 /x put} - \.{dup 1 /y put} - \.{...} - \.{readonly def}} - */ + /* + + At this moment |/Encoding| is the prefix of |t1_line_array|, and the + encoding is not a predefined encoding. We have two possible forms of + vector. The first case is + + \starttyping + /Encoding [ + /a /b /c ... + ] readonly def + \stoptyping + + and the second case can look like + + \starttyping + /Encoding 256 array 0 1 255 { + 1 index exch /.notdef put} for + dup 0 /x put + dup 1 /y put + ... + } readonly def + \stoptyping + + */ t1_encoding = ENC_BUILTIN; if (t1_prefix("/Encoding [") || t1_prefix("/Encoding[")) { /* the first case */ r = strchr(t1_line_array, '[') + 1; skip_char(r, ' '); for (;;) { while (*r == '/') { - for (p = t1_buf_array, r++; - *r != 32 && *r != 10 && *r != ']' && *r != '/'; - *p++ = *r++); + for (p = t1_buf_array, r++; *r != 32 && *r != 10 && *r != ']' && *r != '/'; *p++ = *r++); *p = 0; skip_char(r, ' '); if (counter > 255) @@ -812,16 +801,15 @@ static char **t1_builtin_enc(void) t1_getline(); r = t1_line_array; } - } else { /* the second case */ + } else { + /*tex The second case. */ p = strchr(t1_line_array, 10); for (;;) { if (*p == 10) { t1_getline(); p = t1_line_array; } - /* - check for \.{dup <index> <glyph> put} - */ + /*tex Check for |dup <index> <glyph> put|. */ if (sscanf(p, "dup %i%255s put", &i, t1_buf_array) == 2 && *t1_buf_array == '/' && valid_code(i)) { if (strcmp(t1_buf_array + 1, notdef) != 0) @@ -829,37 +817,25 @@ static char **t1_builtin_enc(void) p = strstr(p, " put") + strlen(" put"); skip_char(p, ' '); } - /* - check for \.{dup dup <to> exch <from> get put} - */ - else if (sscanf(p, "dup dup %i exch %i get put", &b, &a) == 2 - && valid_code(a) && valid_code(b)) { + /*tex Check for |dup dup <to> exch <from> get put|. */ + else if (sscanf(p, "dup dup %i exch %i get put", &b, &a) == 2 && valid_code(a) && valid_code(b)) { copy_glyph_names(glyph_names, a, b); p = strstr(p, " get put") + strlen(" get put"); skip_char(p, ' '); } - /* - check for \.{dup dup <from> <size> getinterval <to> exch putinterval} - */ - else if (sscanf - (p, "dup dup %i %i getinterval %i exch putinterval", - &a, &c, &b) == 3 && valid_code(a) && valid_code(b) - && valid_code(c)) { + /*tex Check for |dup dup <from> <size> getinterval <to> exch putinterval|. */ + else if (sscanf(p, "dup dup %i %i getinterval %i exch putinterval", + &a, &c, &b) == 3 && valid_code(a) && valid_code(b) && valid_code(c)) { for (i = 0; i < c; i++) copy_glyph_names(glyph_names, a + i, b + i); p = strstr(p, " putinterval") + strlen(" putinterval"); skip_char(p, ' '); } - /* - check for \.{def} or \.{readonly def} - */ - else if ((p == t1_line_array || (p > t1_line_array && p[-1] == ' ')) - && strcmp(p, "def\n") == 0) + /*tex Check for |def or |readonly def|. */ + else if ((p == t1_line_array || (p > t1_line_array && p[-1] == ' ')) && strcmp(p, "def\n") == 0) { return glyph_names; - /* - skip an unrecognizable word - */ - else { + } else { + /*tex Skip an unrecognizable word. */ while (*p != ' ' && *p != 10) p++; skip_char(p, ' '); @@ -869,9 +845,6 @@ static char **t1_builtin_enc(void) return glyph_names; } - -@ -@c static void t1_check_end(PDF pdf) { if (t1_eof()) @@ -881,8 +854,6 @@ static void t1_check_end(PDF pdf) t1_putline(pdf); } -@ -@c static boolean t1_open_fontfile(int open_name_prefix) { ff_entry *ff; @@ -939,19 +910,19 @@ static void t1_include(PDF pdf) } while (!t1_end_eexec()); t1_stop_eexec(pdf); - if (fixedcontent) { /* copy 512 zeros (not needed for PDF) */ + if (fixedcontent) { + /*tex Copy 512 zeros (not needed for \PDF). */ do { t1_getline(); t1_putline(pdf); } while (!t1_cleartomark()); - t1_check_end(pdf); /* write "{restore}if" if found */ + /*tex Write |{restore} if| if found. */ + t1_check_end(pdf); } get_length3(); } -@ -@c #define check_subr(subr) \ if (subr >= subr_size || subr < 0) \ formatted_error("type 1","Subrs array: entry index out of range '%i'", subr); @@ -986,10 +957,9 @@ static void cs_store(boolean is_subr) else ptr->name = xstrdup(t1_buf_array + 1); } - /* copy |" RD " + cs data| to |t1_buf_array| */ - memcpy(t1_buf_array, t1_line_array + cs_start - 4, - (unsigned) (t1_cslen + 4)); - /* copy the end of cs data to |t1_buf_array| */ + /*tex Copy |" RD " + cs data| to |t1_buf_array|. */ + memcpy(t1_buf_array, t1_line_array + cs_start - 4, (unsigned) (t1_cslen + 4)); + /*tex Copy the end of cs data to |t1_buf_array|. */ for (p = t1_line_array + cs_start + t1_cslen, t1_buf_ptr = t1_buf_array + t1_cslen + 4; *p != 10; *t1_buf_ptr++ = *p++); *t1_buf_ptr++ = 10; @@ -997,14 +967,12 @@ static void cs_store(boolean is_subr) cs_token_pair = check_cs_token_pair(); ptr->len = (unsigned short) (t1_buf_ptr - t1_buf_array); ptr->cslen = t1_cslen; - xfree(ptr->data); /* mem leak? */ + xfree(ptr->data); ptr->data = xtalloc(ptr->len, byte); memcpy(ptr->data, t1_buf_array, ptr->len); ptr->valid = true; } -@ -@c #define store_subr() cs_store(true) #define store_cs() cs_store(false) @@ -1024,10 +992,9 @@ static boolean is_cc_init = false; goto cs_error; \ } -#define cc_get(N) ((N) < 0 ? *(stack_ptr + (N)) : *(cc_stack + (N))) - -#define cc_push(V) *stack_ptr++ = V -#define cc_clear() stack_ptr = cc_stack +#define cc_get(N) ((N) < 0 ? *(stack_ptr + (N)) : *(cc_stack + (N))) +#define cc_push(V) *stack_ptr++ = V +#define cc_clear() stack_ptr = cc_stack #define set_cc(N, B, A, C) \ cc_tab[N].nargs = A; \ @@ -1052,9 +1019,6 @@ static void cc_init(void) set_cc(CS_CLOSEPATH, false, 0, true); set_cc(CS_CALLSUBR, false, 1, false); set_cc(CS_RETURN, false, 0, false); -#if 0 - set_cc(CS_ESCAPE, false, 0, false); -#endif set_cc(CS_HSBW, true, 2, true); set_cc(CS_ENDCHAR, false, 0, true); set_cc(CS_RMOVETO, true, 2, true); @@ -1073,8 +1037,6 @@ static void cc_init(void) is_cc_init = true; } -@ -@c #define cs_getchar() cdecrypt(*data++, &cr) #define mark_subr(n) cs_mark(0, n) @@ -1093,24 +1055,21 @@ static void cs_fail(const char *cs_name, int subr, const char *fmt, ...) formatted_error("type 1","CharString (/%s): %s", cs_name, buf); } -@ fix a return-less subr by appending |CS_RETURN| -@c +/*tex Fix a return-less subr by appending |CS_RETURN|. */ + static void append_cs_return(cs_entry * ptr) { unsigned short cr; int i; byte *p, *q, *data, *new_data; - assert(ptr != NULL && ptr->valid && ptr->used); - - /* decrypt the cs data to |t1_buf_array|, append |CS_RETURN| */ + /*tex Decrypt the cs data to |t1_buf_array|, append |CS_RETURN|. */ p = (byte *) t1_buf_array; data = ptr->data + 4; cr = 4330; for (i = 0; i < ptr->cslen; i++) *p++ = cs_getchar(); *p = CS_RETURN; - - /* encrypt the new cs data to |new_data| */ + /*tex Encrypt the new cs data to |new_data|. */ new_data = xtalloc((unsigned) (ptr->len + 1), byte); memcpy(new_data, ptr->data, 4); p = new_data + 4; @@ -1119,16 +1078,13 @@ static void append_cs_return(cs_entry * ptr) for (i = 0; i < ptr->cslen + 1; i++) *p++ = cencrypt(*q++, &cr); memcpy(p, ptr->data + 4 + ptr->cslen, (size_t) (ptr->len - ptr->cslen - 4)); - - /* update |*ptr| */ + /*tex Update |*ptr|. */ xfree(ptr->data); ptr->data = new_data; ptr->len++; ptr->cslen++; } -@ -@c static void cs_mark(const char *cs_name, int subr) { byte *data; @@ -1136,8 +1092,8 @@ static void cs_mark(const char *cs_name, int subr) int last_cmd = 0; int a, a1, a2; unsigned short cr; - static int lastargOtherSubr3 = 3; /* the argument of last call to - OtherSubrs[3] */ + /*tex The argument of last call to |OtherSubrs[3]|. */ + static int lastargOtherSubr3 = 3; cs_entry *ptr; cc_entry *cc; if (cs_name == NULL) { @@ -1145,24 +1101,23 @@ static void cs_mark(const char *cs_name, int subr) ptr = subr_tab + subr; if (!ptr->valid) return; - } else { - if (cs_notdef != NULL && - (cs_name == notdef || strcmp(cs_name, notdef) == 0)) - ptr = cs_notdef; - else { - for (ptr = cs_tab; ptr < cs_ptr; ptr++) - if (strcmp(ptr->name, cs_name) == 0) - break; - if (ptr == cs_ptr) { - formatted_warning("type 1","glyph '%s' undefined", cs_name); - return; - } - if (ptr->name == notdef) - cs_notdef = ptr; + } else if (cs_notdef != NULL && (cs_name == notdef || strcmp(cs_name, notdef) == 0)) { + ptr = cs_notdef; + }else { + for (ptr = cs_tab; ptr < cs_ptr; ptr++) + if (strcmp(ptr->name, cs_name) == 0) + break; + if (ptr == cs_ptr) { + formatted_warning("type 1","glyph '%s' undefined", cs_name); + return; } + if (ptr->name == notdef) + cs_notdef = ptr; } - /* only marked CharString entries and invalid entries can be skipped; - valid marked subrs must be parsed to keep the stack in sync */ + /*tex + Only marked CharString entries and invalid entries can be skipped; valid + marked subrs must be parsed to keep the stack in sync. + */ if (!ptr->valid || (ptr->used && cs_name != NULL)) return; ptr->used = true; @@ -1219,42 +1174,43 @@ static void cs_mark(const char *cs_name, int subr) } last_cmd = b; switch (cc - cc_tab) { - case CS_CALLSUBR: - a1 = cc_get(-1); - cc_pop(1); - mark_subr(a1); - if (!subr_tab[a1].valid) { - cs_fail(cs_name, subr, "cannot call subr '%i'", (int) a1); - goto cs_error; - } - break; - case CS_DIV: - cc_pop(2); - cc_push(0); - break; - case CS_CALLOTHERSUBR: - if (cc_get(-1) == 3) - lastargOtherSubr3 = cc_get(-3); - a1 = cc_get(-2) + 2; - cc_pop(a1); - break; - case CS_POP: - cc_push(lastargOtherSubr3); - /* the only case when we care about the value being pushed onto - stack is when POP follows CALLOTHERSUBR (changing hints by - OtherSubrs[3]) - */ - break; - case CS_SEAC: - a1 = cc_get(3); - a2 = cc_get(4); - cc_clear(); - mark_cs(standard_glyph_names[a1]); - mark_cs(standard_glyph_names[a2]); - break; - default: - if (cc->clear) + case CS_CALLSUBR: + a1 = cc_get(-1); + cc_pop(1); + mark_subr(a1); + if (!subr_tab[a1].valid) { + cs_fail(cs_name, subr, "cannot call subr '%i'", (int) a1); + goto cs_error; + } + break; + case CS_DIV: + cc_pop(2); + cc_push(0); + break; + case CS_CALLOTHERSUBR: + if (cc_get(-1) == 3) + lastargOtherSubr3 = cc_get(-3); + a1 = cc_get(-2) + 2; + cc_pop(a1); + break; + case CS_POP: + cc_push(lastargOtherSubr3); + /*tex + The only case when we care about the value being pushed + onto stack is when |POP| follows |CALLOTHERSUBR| changing + hints by |OtherSubrs[3]|. + */ + break; + case CS_SEAC: + a1 = cc_get(3); + a2 = cc_get(4); cc_clear(); + mark_cs(standard_glyph_names[a1]); + mark_cs(standard_glyph_names[a2]); + break; + default: + if (cc->clear) + cc_clear(); } } } @@ -1265,16 +1221,17 @@ static void cs_mark(const char *cs_name, int subr) append_cs_return(ptr); } return; - cs_error: /* an error occured during parsing */ + /*tex An error occured during parsing: */ + cs_error: cc_clear(); ptr->valid = false; ptr->used = false; } -@ AVL search tree for glyph code by glyph name -@c +/* AVL search tree for glyph code by glyph name. */ + static int comp_t1_glyphs(const void *pa, const void *pb, void *p - __attribute__ ((unused))) + __attribute__ ((unused))) { return strcmp(*(const char *const *) pa, *(const char *const *) pb); } @@ -1285,13 +1242,14 @@ static struct avl_table *create_t1_glyph_tree(char **glyph_names) void **aa; static struct avl_table *gl_tree; gl_tree = avl_create(comp_t1_glyphs, NULL, &avl_xallocator); - assert(gl_tree != NULL); for (i = 0; i < 256; i++) { if (glyph_names[i] != notdef && (char **) avl_find(gl_tree, &glyph_names[i]) == NULL) { - /* no |strdup| here, just point to the |glyph_names| array members */ + /*tex No |strdup| here, just point to the |glyph_names| array members. */ aa = avl_probe(gl_tree, &glyph_names[i]); - assert(aa != NULL); + if (aa == NULL) { + /*tex Is this a problem? */ + } } } return gl_tree; @@ -1299,12 +1257,9 @@ static struct avl_table *create_t1_glyph_tree(char **glyph_names) static void destroy_t1_glyph_tree(struct avl_table *gl_tree) { - assert(gl_tree != NULL); avl_destroy(gl_tree, NULL); } -@ -@c static void t1_subset_ascii_part(PDF pdf) { int j, *p; @@ -1312,8 +1267,6 @@ static void t1_subset_ascii_part(PDF pdf) struct avl_table *gl_tree; struct avl_traverser t; void **aa; - assert(fd_cur != NULL); - assert(fd_cur->gl_tree != NULL); t1_getline(); while (!t1_prefix("/Encoding")) { t1_scan_param(pdf); @@ -1323,9 +1276,8 @@ static void t1_subset_ascii_part(PDF pdf) glyph_names = t1_builtin_enc(); fd_cur->builtin_glyph_names = glyph_names; if (is_subsetted(fd_cur->fm)) { - assert(is_included(fd_cur->fm)); if (fd_cur->tx_tree != NULL) { - /* take over collected non-reencoded characters from \TeX */ + /*tex Take over collected non-reencoded characters from \TeX. */ avl_t_init(&t, fd_cur->tx_tree); for (p = (int *) avl_t_first(&t, fd_cur->tx_tree); p != NULL; p = (int *) avl_t_next(&t)) { @@ -1337,46 +1289,44 @@ static void t1_subset_ascii_part(PDF pdf) } } make_subset_tag(fd_cur); - assert(t1_fontname_offset != 0); strncpy((char *) pdf->fb->data + t1_fontname_offset, fd_cur->subset_tag,6); } - /* now really all glyphs needed from this font are in the |fd_cur->gl_tree| */ + /*tex Now really all glyphs needed from this font are in the |fd_cur->gl_tree|. */ if (t1_encoding == ENC_STANDARD) t1_puts(pdf, "/Encoding StandardEncoding def\n"); else { - t1_puts - (pdf, - "/Encoding 256 array\n0 1 255 {1 index exch /.notdef put} for\n"); + t1_puts(pdf,"/Encoding 256 array\n0 1 255 {1 index exch /.notdef put} for\n"); gl_tree = create_t1_glyph_tree(glyph_names); avl_t_init(&t, fd_cur->gl_tree); j = 0; for (glyph = (char *) avl_t_first(&t, fd_cur->gl_tree); glyph != NULL; glyph = (char *) avl_t_next(&t)) { if ((gg = (char **) avl_find(gl_tree, &glyph)) != NULL) { - t1_printf(pdf, "dup %i /%s put\n", (int) (gg - glyph_names), - *gg); + t1_printf(pdf, "dup %i /%s put\n", (int) (gg - glyph_names),*gg); j++; } } destroy_t1_glyph_tree(gl_tree); - if (j == 0) - /* We didn't mark anything for the Encoding array. - We add \.{dup 0 /.notdef put} for compatibility with Acrobat 5.0. */ + if (j == 0) { + /*tex + We didn't mark anything for the Encoding array. We add |{dup 0 + /.notdef put}| for compatibility with Acrobat 5.0. + */ t1_puts(pdf, "dup 0 /.notdef put\n"); + } t1_puts(pdf, "readonly def\n"); } do { t1_getline(); t1_scan_param(pdf); - if (!t1_prefix("/UniqueID")) /* ignore UniqueID for subsetted fonts */ + if (!t1_prefix("/UniqueID")) { + /*tex Ignore |/UniqueID| for subsetted fonts. */ t1_putline(pdf); + } } while (t1_in_eexec == 0); } - -@ -@c static void cs_init(void) { cs_ptr = cs_tab = NULL; @@ -1398,8 +1348,6 @@ static void init_cs_entry(cs_entry * cs) cs->valid = false; } -@ -@c static void t1_read_subrs(PDF pdf) { int i, s; @@ -1407,8 +1355,10 @@ static void t1_read_subrs(PDF pdf) t1_getline(); while (!(t1_charstrings() || t1_subrs())) { t1_scan_param(pdf); - if (!t1_prefix("/UniqueID")) /* ignore UniqueID for subsetted fonts */ + if (!t1_prefix("/UniqueID")) { + /*tex Ignore |/UniqueID| for subsetted fonts. */ t1_putline(pdf); + } t1_getline(); } found: @@ -1417,7 +1367,7 @@ static void t1_read_subrs(PDF pdf) if (!t1_subrs()) return; subr_size_pos = strlen("/Subrs") + 1; - /* |subr_size_pos| points to the number indicating dict size after |"Subrs"| */ + /*tex |subr_size_pos| points to the number indicating dict size after |Subrs|. */ subr_size = (int) t1_scan_num(t1_line_array + subr_size_pos, 0); if (subr_size == 0) { while (!t1_charstrings()) @@ -1433,17 +1383,20 @@ static void t1_read_subrs(PDF pdf) store_subr(); t1_getline(); } - /* mark the first four entries without parsing */ + /*tex Mark the first four entries without parsing. */ for (i = 0; i < subr_size && i < 4; i++) subr_tab[i].used = true; - /* the end of the Subrs array might have more than one line so we need to - concatenate them to |subr_array_end|. Unfortunately some fonts don't have - the Subrs array followed by the CharStrings dict immediately (synthetic - fonts). If we cannot find CharStrings in next |POST_SUBRS_SCAN| lines then - we will treat the font as synthetic and ignore everything until next - Subrs is found + /*tex + + The end of the |Subrs| array might have more than one line so we need to + concatenate them to |subr_array_end|. Unfortunately some fonts don't have + the |Subrs| array followed by the |CharStrings| dict immediately (synthetic + fonts). If we cannot find |CharStrings| in next |POST_SUBRS_SCAN| lines + then we will treat the font as synthetic and ignore everything until next + |Subrs| is found. + */ -#define POST_SUBRS_SCAN 5 +#define POST_SUBRS_SCAN 5 s = 0; *t1_buf_array = 0; for (i = 0; i < POST_SUBRS_SCAN; i++) { @@ -1455,8 +1408,8 @@ static void t1_read_subrs(PDF pdf) t1_getline(); } subr_array_end = xstrdup(t1_buf_array); - if (i == POST_SUBRS_SCAN) { /* CharStrings not found; - suppose synthetic font */ + if (i == POST_SUBRS_SCAN) { + /*tex |CharStrings| not found: assume a synthetic font. */ for (ptr = subr_tab; ptr - subr_tab < subr_size; ptr++) if (ptr->valid) xfree(ptr->data); @@ -1472,8 +1425,6 @@ static void t1_read_subrs(PDF pdf) } } -@ -@c #define t1_subr_flush() t1_flush_cs(pdf, true) #define t1_cs_flush() t1_flush_cs(pdf, false) @@ -1509,21 +1460,22 @@ static void t1_flush_cs(PDF pdf, boolean is_subr) strcat(t1_line_ptr, p); t1_line_ptr = eol(t1_line_array); t1_putline(pdf); - - cs_len = 0; /* for -Wall */ - /* create |return_cs| to replace unsused subr's */ + /*tex For |-Wall|. */ + cs_len = 0; + /*tex Create |return_cs| to replace unsused |subr|s. */ if (is_subr) { cr = 4330; cs_len = 0; - /* at this point we have |t1_lenIV >= 0;| - a negative value would be caught in |t1_scan_param| */ + /*tex + At this point we have |t1_lenIV >= 0;| a negative value would be + caught in |t1_scan_param|. + */ return_cs = xtalloc((unsigned) (t1_lenIV + 1), byte); for (cs_len = 0, r = return_cs; cs_len < t1_lenIV; cs_len++, r++) *r = cencrypt(0x00, &cr); *r = cencrypt(CS_RETURN, &cr); cs_len++; } - for (ptr = tab; ptr < end_tab; ptr++) { if (ptr->used) { if (is_subr) @@ -1536,7 +1488,7 @@ static void t1_flush_cs(PDF pdf, boolean is_subr) t1_line_ptr = p + ptr->len; t1_putline(pdf); } else { - /* replace unsused subr's by |return_cs| */ + /*tex Replace unsused subr's by |return_cs|. */ if (is_subr) { sprintf(t1_line_array, "dup %li %u%s ", (long int) (ptr - tab), cs_len, cs_token_pair[0]); @@ -1550,8 +1502,8 @@ static void t1_flush_cs(PDF pdf, boolean is_subr) } } xfree(ptr->data); - if (is_subr) - ptr->valid=false; + if (is_subr) + ptr->valid = false; if (ptr->name != notdef) xfree(ptr->name); } @@ -1560,28 +1512,27 @@ static void t1_flush_cs(PDF pdf, boolean is_subr) t1_putline(pdf); if (is_subr) { end_tab = subr_tab + subr_size; - for (ptr = tab; ptr < end_tab; ptr++) { - if (ptr->valid) { - xfree(ptr->data); - if (ptr->name != notdef) - xfree(ptr->name); - } + for (ptr = tab; ptr < end_tab; ptr++) { + if (ptr->valid) { + xfree(ptr->data); + if (ptr->name != notdef) + xfree(ptr->name); + } } - xfree(return_cs); + xfree(return_cs); } xfree(tab); xfree(start_line); xfree(line_end); } -@ -@c static void t1_mark_glyphs(void) { char *glyph; struct avl_traverser t; cs_entry *ptr; - if (t1_synthetic || fd_cur->all_glyphs) { /* mark everything */ + if (t1_synthetic || fd_cur->all_glyphs) { + /*tex Mark everything. */ if (cs_tab != NULL) for (ptr = cs_tab; ptr < cs_ptr; ptr++) if (ptr->valid) @@ -1607,21 +1558,26 @@ static void t1_mark_glyphs(void) } -@ When |t1_subset_charstrings| is called, the |t1_line_array| contains \.{/CharStrings}. -When we hit a case like this: -{\obeylines \tt - dup/CharStrings - 229 dict dup begin -} -we read the next line and concatenate to |t1_line_array| before moving on. That is -what |t1_check_unusual_charstring| is for. +/*tex + + When |t1_subset_charstrings| is called, the |t1_line_array| contains + |/CharStrings|. When we hit a case like this: + + \starttyping + dup/CharStrings + 229 dict dup begin + \stoptyping + + we read the next line and concatenate to |t1_line_array| before moving on. + That is what |t1_check_unusual_charstring| is for. + +*/ -@c static void t1_check_unusual_charstring(void) { char *p = strstr(t1_line_array, charstringname) + strlen(charstringname); int i; - /* if no number follows "/CharStrings", let's read the next line */ + /*tex If no number follows |/CharStrings|, let's read the next line. */ if (sscanf(p, "%i", &i) != 1) { strcpy(t1_buf_array, t1_line_array); t1_getline(); @@ -1634,14 +1590,9 @@ static void t1_check_unusual_charstring(void) static void t1_subset_charstrings(PDF pdf) { cs_entry *ptr; - t1_check_unusual_charstring(); - - cs_size_pos = (int) (strstr(t1_line_array, - charstringname) + strlen(charstringname) - - t1_line_array + 1); - /* |cs_size_pos| points to the number indicating - dict size after |"/CharStrings"| */ + cs_size_pos = (int) (strstr(t1_line_array, charstringname) + strlen(charstringname) - t1_line_array + 1); + /*tex |cs_size_pos| points to the number indicating dict size after |/CharStrings|. */ cs_size = (int) t1_scan_num(t1_line_array + cs_size_pos, 0); cs_ptr = cs_tab = xtalloc((unsigned) cs_size, cs_entry); for (ptr = cs_tab; ptr - cs_tab < cs_size; ptr++) @@ -1656,12 +1607,9 @@ static void t1_subset_charstrings(PDF pdf) cs_dict_end = xstrdup(t1_line_array); t1_mark_glyphs(); if (subr_tab != NULL) { - - if (cs_token_pair == NULL) formatted_error("type 1","mismatched subroutine begin/end token pairs"); t1_subr_flush(); - } for (cs_counter = 0, ptr = cs_tab; ptr < cs_ptr; ptr++) if (ptr->used) @@ -1669,46 +1617,54 @@ static void t1_subset_charstrings(PDF pdf) t1_cs_flush(); } -@ -@c static void t1_subset_end(PDF pdf) { - if (t1_synthetic) { /* copy to \.{dup /FontName get exch definefont pop} */ + if (t1_synthetic) { + /*tex Copy to |dup /FontName get exch definefont pop|. */ while (!strstr(t1_line_array, "definefont")) { t1_getline(); t1_putline(pdf); } - while (!t1_end_eexec()) - t1_getline(); /* ignore the rest */ - t1_putline(pdf); /* write \.{mark currentfile closefile} */ - } else - while (!t1_end_eexec()) { /* copy to \.{mark currentfile closefile} */ + while (!t1_end_eexec()) { + /*tex Ignore the rest. */ + t1_getline(); + } + /*tex Write \.{mark currentfile closefile}. */ + t1_putline(pdf); + } else { + while (!t1_end_eexec()) { + /*tex Copy to \.{mark currentfile closefile}. */ t1_getline(); t1_putline(pdf); } + } t1_stop_eexec(pdf); - if (fixedcontent) { /* copy 512 zeros (not needed for PDF) */ + if (fixedcontent) { + /*tex Copy 512 zeros (not needed for PDF). */ while (!t1_cleartomark()) { t1_getline(); t1_putline(pdf); } - if (!t1_synthetic) /* don't check \.{{restore}if} for synthetic fonts */ - t1_check_end(pdf); /* write \.{{restore}if} if found */ + /*tex Don't check \.{{restore}if} for synthetic fonts. */ + if (!t1_synthetic) { + /*tex Write \.{{restore}if} if found. */ + t1_check_end(pdf); + } } get_length3(); } -@ -@c void writet1(PDF pdf, fd_entry * fd) { - fd_cur = fd; /* |fd_cur| is global inside \.{writet1.w} */ + /*tex |fd_cur| is global inside |writet1.c|. */ + fd_cur = fd; assert(fd_cur->fm != NULL); assert(is_type1(fd->fm)); assert(is_included(fd->fm)); t1_save_offset = 0; - if (!is_subsetted(fd_cur->fm)) { /* include entire font */ + if (!is_subsetted(fd_cur->fm)) { + /*tex Include entire font. */ if (!(fd->ff_found = t1_open_fontfile(filetype_font))) return; t1_include(pdf); @@ -1716,7 +1672,7 @@ void writet1(PDF pdf, fd_entry * fd) xfree(t1_buffer); return; } - /* partial downloading */ + /*tex Partial downloading. */ if (!(fd->ff_found = t1_open_fontfile(filetype_subset))) return; t1_subset_ascii_part(pdf); @@ -1730,8 +1686,6 @@ void writet1(PDF pdf, fd_entry * fd) xfree(t1_buffer); } -@ -@c void t1_free(void) { xfree(t1_line_array); diff --git a/Build/source/texk/web2c/luatexdir/font/writet3.w b/Build/source/texk/web2c/luatexdir/font/writet3.c index 879cef8d5a0..6121c24a1f0 100644 --- a/Build/source/texk/web2c/luatexdir/font/writet3.w +++ b/Build/source/texk/web2c/luatexdir/font/writet3.c @@ -1,25 +1,24 @@ -% writet3.w -% -% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org> -% Copyright 2006-2011 Taco Hoekwater <taco@@luatex.org> -% -% This file is part of LuaTeX. -% -% LuaTeX 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. -% -% LuaTeX 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 Lesser General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License along -% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +/* -@ @c +Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> +Copyright 2006-2011 Taco Hoekwater <taco@luatex.org> +This file is part of LuaTeX. + +LuaTeX 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. + +LuaTeX 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU General Public License along +with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +*/ #include "ptexlib.h" #include <kpathsea/tex-glyph.h> @@ -41,7 +40,8 @@ static float t3_font_scale; static int t3_b0, t3_b1, t3_b2, t3_b3; static boolean is_pk_font; -/* not static because used by pkin.c */ +/*tex Not static because used elsewhere. */ + unsigned char *t3_buffer = NULL; int t3_size = 0; int t3_curbyte = 0; @@ -50,8 +50,6 @@ int t3_curbyte = 0; if (t3_eof()) \ normal_error("type 3","unexpected end of file"); -@ -@c static void update_bbox(int llx, int lly, int urx, int ury, boolean is_first_glyph) { if (is_first_glyph) { @@ -71,7 +69,7 @@ static void update_bbox(int llx, int lly, int urx, int ury, boolean is_first_gly } } -/* fixed precision 3 (+5 in pdfgen.w)*/ +/*tex Fixed precision 3 (+5 in |pdfgen.c|)*/ #define get_pk_font_scale(pdf,f,scale_factor) \ divide_scaled(scale_factor, divide_scaled(font_size(f),one_hundred_bp,pk_decimal_digits(pdf,2)), 0) @@ -79,8 +77,6 @@ static void update_bbox(int llx, int lly, int urx, int ury, boolean is_first_gly #define pk_char_width(pdf,f,w,scale_factor) \ divide_scaled(divide_scaled(w,font_size(f),pk_decimal_digits(pdf,4)), get_pk_font_scale(pdf,f,scale_factor), 0) -@ -@c static boolean writepk(PDF pdf, internal_font_number f) { kpse_glyph_file_type font_ret; @@ -98,17 +94,14 @@ static boolean writepk(PDF pdf, internal_font_number f) xfree(t3_buffer); t3_curbyte = 0; t3_size = 0; - callback_id = callback_defined(find_pk_file_callback); - if (pdf->pk_fixed_dpi) { newdpi = pdf->pk_resolution; } else { newdpi = dpi; } - if (callback_id > 0) { - /* <base>.dpi/<fontname>.<tdpi>pk */ + /*tex |<base>.dpi/<fontname>.<tdpi>pk| */ dpi = round((float) pdf->pk_resolution * (((float) font_size(f)) / (float) font_dsize(f))); cur_file_name = font_name(f); run_callback(callback_id, "Sd->S", cur_file_name, (int) newdpi, &name); @@ -213,8 +206,6 @@ static boolean writepk(PDF pdf, internal_font_number f) return true; } -@ -@c void writet3(PDF pdf, internal_font_number f) { int i; @@ -224,7 +215,6 @@ void writet3(PDF pdf, internal_font_number f) int pk_font_scale; pdffloat pf; boolean is_notdef; - t3_glyph_num = 0; t3_image_used = false; for (i = 0; i < 256; i++) { @@ -232,7 +222,6 @@ void writet3(PDF pdf, internal_font_number f) t3_char_widths[i] = 0; } is_pk_font = false; - xfree(t3_buffer); t3_curbyte = 0; t3_size = 0; @@ -246,8 +235,7 @@ void writet3(PDF pdf, internal_font_number f) if (pdf_char_marked(f, i)) break; last_char = i; - - /* Type 3 font dictionary */ + /*tex We create a |Type3| font dictionary: */ pdf_begin_obj(pdf, pdf_font_num(f), OBJSTM_ALWAYS); pdf_begin_dict(pdf); pdf_dict_add_name(pdf, "Type", "Font"); @@ -302,8 +290,7 @@ void writet3(PDF pdf, internal_font_number f) pdf_dict_add_ref(pdf, "CharProcs", (int) cptr); pdf_end_dict(pdf); pdf_end_obj(pdf); - - /* chars width array */ + /*tex The |Widths| array: */ pdf_begin_obj(pdf, wptr, OBJSTM_ALWAYS); pdf_begin_array(pdf); if (is_pk_font) { @@ -319,8 +306,7 @@ void writet3(PDF pdf, internal_font_number f) } pdf_end_array(pdf); pdf_end_obj(pdf); - - /* encoding dictionary */ + /*tex The |Encoding| dictionary: */ pdf_begin_obj(pdf, eptr, OBJSTM_ALWAYS); pdf_begin_dict(pdf); pdf_dict_add_name(pdf, "Type", "Encoding"); @@ -354,8 +340,7 @@ void writet3(PDF pdf, internal_font_number f) pdf_end_array(pdf); pdf_end_dict(pdf); pdf_end_obj(pdf); - - /* CharProcs dictionary */ + /*tex The |CharProcs| dictionary: */ pdf_begin_obj(pdf, cptr, OBJSTM_ALWAYS); pdf_begin_dict(pdf); for (i = first_char; i <= last_char; i++) { diff --git a/Build/source/texk/web2c/luatexdir/font/writettf.w b/Build/source/texk/web2c/luatexdir/font/writettf.c index 4a016cbe403..cf034e98d0a 100644 --- a/Build/source/texk/web2c/luatexdir/font/writettf.w +++ b/Build/source/texk/web2c/luatexdir/font/writettf.c @@ -1,32 +1,31 @@ -% writettf.w -% -% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org> -% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org> -% -% This file is part of LuaTeX. -% -% LuaTeX 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. -% -% LuaTeX 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 Lesser General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License along -% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. - -@ @c +/* +Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> +Copyright 2006-2010 Taco Hoekwater <taco@luatex.org> + +This file is part of LuaTeX. + +LuaTeX 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. + +LuaTeX 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU General Public License along +with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +*/ #include "ptexlib.h" #include "font/writettf.h" #include <string.h> #define DEFAULT_NTABS 14 -#define NEW_CMAP_SIZE 2 +#define NEW_CMAP_SIZE 2 #define ttf_putchar(A) strbuf_putchar(pdf->fb, (A)) #define ttf_offset() strbuf_offset(pdf->fb) @@ -37,8 +36,10 @@ int ttf_size = 0; int ttf_curbyte = 0; typedef struct { - char *name; /* name of glyph */ - long newindex; /* new index of glyph in output file */ + /*tex the name of glyph */ + char *name; + /*tex the new index of glyph in output file */ + long newindex; } ttfenc_entry; @@ -87,303 +88,88 @@ static TTF_ULONG checkSumAdjustment_offset; FILE *ttf_file; static ttfenc_entry ttfenc_tab[256]; -fd_entry *fd_cur; /* pointer to the current font descriptor */ +/*tex A pointer to the current font descriptor: */ + +fd_entry *fd_cur; static struct avl_table *ttf_cmap_tree = NULL; int ttf_length; -@ This used to be macnames.c - -@c char notdef[] = ".notdef"; const char *mac_glyph_names[] = { -/* 0x00 */ - notdef, - ".null", - "CR", - "space", - "exclam", - "quotedbl", - "numbersign", - "dollar", - "percent", - "ampersand", - "quotesingle", - "parenleft", - "parenright", - "asterisk", - "plus", - "comma", -/* 0x10 */ - "hyphen", - "period", - "slash", - "zero", - "one", - "two", - "three", - "four", - "five", - "six", - "seven", - "eight", - "nine", - "colon", - "semicolon", - "less", -/* 0x20 */ - "equal", - "greater", - "question", - "at", - "A", - "B", - "C", - "D", - "E", - "F", - "G", - "H", - "I", - "J", - "K", - "L", -/* 0x30 */ - "M", - "N", - "O", - "P", - "Q", - "R", - "S", - "T", - "U", - "V", - "W", - "X", - "Y", - "Z", - "bracketleft", - "backslash", -/* 0x40 */ - "bracketright", - "asciicircum", - "underscore", - "grave", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", -/* 0x50 */ - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "braceleft", - "bar", -/* 0x60 */ - "braceright", - "asciitilde", - "Adieresis", - "Aring", - "Ccedilla", - "Eacute", - "Ntilde", - "Odieresis", - "Udieresis", - "aacute", - "agrave", - "acircumflex", - "adieresis", - "atilde", - "aring", - "ccedilla", -/* 0x70 */ - "eacute", - "egrave", - "ecircumflex", - "edieresis", - "iacute", - "igrave", - "icircumflex", - "idieresis", - "ntilde", - "oacute", - "ograve", - "ocircumflex", - "odieresis", - "otilde", - "uacute", - "ugrave", -/* 0x80 */ - "ucircumflex", - "udieresis", - "dagger", - "degree", - "cent", - "sterling", - "section", - "bullet", - "paragraph", - "germandbls", - "registered", - "copyright", - "trademark", - "acute", - "dieresis", - "notequal", -/* 0x90 */ - "AE", - "Oslash", - "infinity", - "plusminus", - "lessequal", - "greaterequal", - "yen", - "mu", - "partialdiff", - "Sigma", - "Pi", - "pi", - "integral", - "ordfeminine", - "ordmasculine", - "Omega", -/* 0xa0 */ - "ae", - "oslash", - "questiondown", - "exclamdown", - "logicalnot", - "radical", - "florin", - "approxequal", - "Delta", - "guillemotleft", - "guillemotright", - "ellipsis", - "nbspace", - "Agrave", - "Atilde", - "Otilde", -/* 0xb0 */ - "OE", - "oe", - "endash", - "emdash", - "quotedblleft", - "quotedblright", - "quoteleft", - "quoteright", - "divide", - "lozenge", - "ydieresis", - "Ydieresis", - "fraction", - "currency", - "guilsinglleft", - "guilsinglright", -/* 0xc0 */ - "fi", - "fl", - "daggerdbl", - "periodcentered", - "quotesinglbase", - "quotedblbase", - "perthousand", - "Acircumflex", - "Ecircumflex", - "Aacute", - "Edieresis", - "Egrave", - "Iacute", - "Icircumflex", - "Idieresis", - "Igrave", -/* 0xd0 */ - "Oacute", - "Ocircumflex", - "applelogo", - "Ograve", - "Uacute", - "Ucircumflex", - "Ugrave", - "dotlessi", - "circumflex", - "tilde", - "macron", - "breve", - "dotaccent", - "ring", - "cedilla", - "hungarumlaut", -/* 0xe0 */ - "ogonek", - "caron", - "Lslash", - "lslash", - "Scaron", - "scaron", - "Zcaron", - "zcaron", - "brokenbar", - "Eth", - "eth", - "Yacute", - "yacute", - "Thorn", - "thorn", + /* 0x00 */ + notdef, ".null", "CR", "space", "exclam", "quotedbl", "numbersign", "dollar", + "percent", "ampersand", "quotesingle", "parenleft", "parenright", "asterisk", + "plus", "comma", + /* 0x10 */ + "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", + "six", "seven", "eight", "nine", "colon", "semicolon", "less", + /* 0x20 */ + "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", + "I", "J", "K", "L", + /* 0x30 */ + "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", + "bracketleft", "backslash", + /* 0x40 */ + "bracketright", "asciicircum", "underscore", "grave", "a", "b", "c", "d", + "e", "f", "g", "h", "i", "j", "k", "l", + /* 0x50 */ + "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", + "braceleft", "bar", + /* 0x60 */ + "braceright", "asciitilde", "Adieresis", "Aring", "Ccedilla", "Eacute", + "Ntilde", "Odieresis", "Udieresis", "aacute", "agrave", "acircumflex", + "adieresis", "atilde", "aring", "ccedilla", + /* 0x70 */ + "eacute", "egrave", "ecircumflex", "edieresis", "iacute", "igrave", + "icircumflex", "idieresis", "ntilde", "oacute", "ograve", "ocircumflex", + "odieresis", "otilde", "uacute", "ugrave", + /* 0x80 */ + "ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling", + "section", "bullet", "paragraph", "germandbls", "registered", "copyright", + "trademark", "acute", "dieresis", "notequal", + /* 0x90 */ + "AE", "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", "yen", + "mu", "partialdiff", "Sigma", "Pi", "pi", "integral", "ordfeminine", + "ordmasculine", "Omega", + /* 0xa0 */ + "ae", "oslash", "questiondown", "exclamdown", "logicalnot", "radical", + "florin", "approxequal", "Delta", "guillemotleft", "guillemotright", + "ellipsis", "nbspace", "Agrave", "Atilde", "Otilde", + /* 0xb0 */ + "OE", "oe", "endash", "emdash", "quotedblleft", "quotedblright", "quoteleft", + "quoteright", "divide", "lozenge", "ydieresis", "Ydieresis", "fraction", + "currency", "guilsinglleft", "guilsinglright", + /* 0xc0 */ + "fi", "fl", "daggerdbl", "periodcentered", "quotesinglbase", "quotedblbase", + "perthousand", "Acircumflex", "Ecircumflex", "Aacute", "Edieresis", "Egrave", + "Iacute", "Icircumflex", "Idieresis", "Igrave", + /* 0xd0 */ + "Oacute", "Ocircumflex", "applelogo", "Ograve", "Uacute", "Ucircumflex", + "Ugrave", "dotlessi", "circumflex", "tilde", "macron", "breve", "dotaccent", + "ring", "cedilla", "hungarumlaut", + /* 0xe0 */ + "ogonek", "caron", "Lslash", "lslash", "Scaron", "scaron", "Zcaron", + "zcaron", "brokenbar", "Eth", "eth", "Yacute", "yacute", "Thorn", "thorn", "minus", -/* 0xf0 */ - "multiply", - "onesuperior", - "twosuperior", - "threesuperior", - "onehalf", - "onequarter", - "threequarters", - "franc", - "Gbreve", - "gbreve", - "Idot", - "Scedilla", - "scedilla", - "Cacute", - "cacute", - "Ccaron", -/* 0x100 */ - "ccaron", - "dmacron" + /* 0xf0 */ + "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf", + "onequarter", "threequarters", "franc", "Gbreve", "gbreve", "Idot", + "Scedilla", "scedilla", "Cacute", "cacute", "Ccaron", + /* 0x100 */ + "ccaron", "dmacron" }; const char *ambiguous_names[] = { - "Delta", /* increment */ - "Omega", /* Ohm */ - "Pi", /* product */ - "Sigma", /* summation */ - "dmacron", /* dslash */ - "macron", /* overscore */ - "periodcentered", /* middot */ + "Delta", /* increment */ + "Omega", /* Ohm */ + "Pi", /* product */ + "Sigma", /* summation */ + "dmacron", /* dslash */ + "macron", /* overscore */ + "periodcentered", /* middot */ NULL }; @@ -404,9 +190,8 @@ static const char *newtabnames[] = { "prep" }; -@ Back to code. Low-level helpers first. +/* Back to code. Low-level helpers first. */ -@c static ttf_cmap_entry *new_ttf_cmap_entry(void) { ttf_cmap_entry *e; @@ -438,7 +223,6 @@ static int comp_ttf_cmap_entry(const void *pa, const void *pb, void *p) *p2 = (const ttf_cmap_entry *) pb; int i; (void) p; - assert(p1->ttf_name != NULL && p2->ttf_name != NULL); if ((i = strcmp(p1->ttf_name, p2->ttf_name)) != 0) return i; cmp_return(p1->pid, p2->pid); @@ -459,8 +243,10 @@ static unsigned char ttf_addchksm(unsigned char b) static TTF_ULONG ttf_getchksm(PDF pdf) { - while (tab_length % 4 != 0) - ttf_putchar(ttf_addchksm(0)); /* |ttf_addchksm| updates |tab_length| */ + while (tab_length % 4 != 0) { + /*tex |ttf_addchksm| updates |tab_length| */ + ttf_putchar(ttf_addchksm(0)); + } return checksum; } @@ -539,48 +325,34 @@ static void ttf_copy_encoding(void) int i, *q; void **aa; char **glyph_names; - /*long *charcodes;*/ - /*static char buf[SMALL_BUF_SIZE];*/ struct avl_traverser t; - /*ttfenc_entry *e = ttfenc_tab;*/ - - assert(fd_cur->tx_tree != NULL); /* this must be set in |create_fontdictionary| */ - if (fd_cur->fe != NULL) { glyph_names = fd_cur->fe->glyph_names; - assert(glyph_names != NULL); - for (i = 0; i < 256; i++) ttfenc_tab[i].name = (char *) notdef; - - /* a workaround for a bug of AcroReader 4.0 */ + /*tex This is a workaround for a bug of AcroReader 4.0: */ if (strcmp(glyph_names[97], "a") == 0) { q = xtalloc(1, int); *q = 'a'; aa = avl_probe(fd_cur->tx_tree, q); - assert(aa != NULL); + if (aa == NULL) { + /*tex Is this a problem? */ + } } - /* end of workaround */ - - /* take over collected characters from \TeX, reencode them */ + /*tex Take over collected characters from \TeX, reencode them. */ avl_t_init(&t, fd_cur->tx_tree); - for (q = (int *) avl_t_first(&t, fd_cur->tx_tree); q != NULL; - q = (int *) avl_t_next(&t)) { - assert(*q >= 0 && *q < 256); + for (q = (int *) avl_t_first(&t, fd_cur->tx_tree); q != NULL; q = (int *) avl_t_next(&t)) { ttfenc_tab[*q].name = glyph_names[*q]; } make_subset_tag(fd_cur); - } else - assert(0); + } } -@ -@c -#define ttf_append_byte(B)\ -do {\ - if (name_tab[i].platform_id == 3)\ - *q++ = 0;\ - *q++ = B;\ +#define ttf_append_byte(B) do { \ + if (name_tab[i].platform_id == 3) { \ + *q++ = 0; \ + } \ + *q++ = B; \ } while (0) static char *strip_spaces_and_delims(char *s, int l) @@ -588,9 +360,6 @@ static char *strip_spaces_and_delims(char *s, int l) static char buf[SMALL_BUF_SIZE]; char *p = buf; int i; - - assert(l >= 0 && l < (int) sizeof(buf)); - for (i = 0; i < l; s++, i++) { if (*s == '(' || *s == ')' || *s == '<' || *s == '>' || *s == '[' || *s == ']' || *s == '{' || *s == '}' || @@ -609,9 +378,7 @@ static void ttf_read_name(void) char *p, buf[SMALL_BUF_SIZE]; name_record_num = get_ushort(); name_tab = xtalloc((unsigned) name_record_num, name_record); - name_buf_size = (int) ((unsigned) tab->length - - (3 * TTF_USHORT_SIZE + - (TTF_ULONG) name_record_num * 6 * TTF_USHORT_SIZE)); + name_buf_size = (int) ((unsigned) tab->length - (3 * TTF_USHORT_SIZE + (TTF_ULONG) name_record_num * 6 * TTF_USHORT_SIZE)); name_buf = xtalloc((unsigned) name_buf_size, char); ttf_skip(TTF_USHORT_SIZE); for (i = 0; i < name_record_num; i++) { @@ -624,14 +391,12 @@ static void ttf_read_name(void) } for (p = name_buf; p - name_buf < name_buf_size; p++) *p = get_char(); - /* look for PS font name */ + /*tex Look for the \POSTSCRIPT\ font name. */ for (i = 0; i < name_record_num; i++) { if (name_tab[i].platform_id == 1 && name_tab[i].encoding_id == 0 && name_tab[i].name_id == 6) { xfree(fd_cur->fontname); - fd_cur->fontname = - xstrdup(strip_spaces_and_delims(name_buf + name_tab[i].offset, - name_tab[i].length)); + fd_cur->fontname = xstrdup(strip_spaces_and_delims(name_buf + name_tab[i].offset, name_tab[i].length)); fd_cur->font_dim[FONTNAME_CODE].set = true; break; } @@ -639,15 +404,14 @@ static void ttf_read_name(void) if (!fd_cur->font_dim[FONTNAME_CODE].set) { for (i = 0; i < name_record_num; i++) { if (name_tab[i].platform_id == 3 && - (name_tab[i].encoding_id == 0 || name_tab[i].encoding_id == 1) - && name_tab[i].name_id == 6) { + (name_tab[i].encoding_id == 0 || name_tab[i].encoding_id == 1) + && name_tab[i].name_id == 6) { xfree(fd_cur->fontname); assert(name_tab[i].length < sizeof(buf)); for (j = 0, p = buf; j < name_tab[i].length; j += 2) *p++ = name_buf[name_tab[i].offset + j + 1]; *p = 0; - fd_cur->fontname = - xstrdup(strip_spaces_and_delims(buf, (int) strlen(buf))); + fd_cur->fontname = xstrdup(strip_spaces_and_delims(buf, (int) strlen(buf))); fd_cur->font_dim[FONTNAME_CODE].set = true; break; } @@ -659,8 +423,7 @@ static void ttf_read_mapx(void) { glyph_entry *glyph; ttf_seek_tab("maxp", TTF_FIXED_SIZE); - glyph_tab = - xtalloc((unsigned) (1 + (glyphs_count = get_ushort())), glyph_entry); + glyph_tab = xtalloc((unsigned) (1 + (glyphs_count = get_ushort())), glyph_entry); for (glyph = glyph_tab; glyph - glyph_tab < glyphs_count; glyph++) { glyph->newindex = -1; glyph->newoffset = 0; @@ -668,14 +431,15 @@ static void ttf_read_mapx(void) glyph->name = (char *) notdef; } glyph_index = xtalloc((unsigned) (glyphs_count + 1), long); - glyph_index[0] = 0; /* index of ".notdef" glyph */ - glyph_index[1] = 1; /* index of ".null" glyph */ + /*tex index of the |.notdef| glyph */ + glyph_index[0] = 0; + /*tex index of the |.null| glyph */ + glyph_index[1] = 1; } void ttf_read_head(void) { - ttf_seek_tab("head", - 2 * TTF_FIXED_SIZE + 2 * TTF_ULONG_SIZE + TTF_USHORT_SIZE); + ttf_seek_tab("head", 2 * TTF_FIXED_SIZE + 2 * TTF_ULONG_SIZE + TTF_USHORT_SIZE); upem = get_ushort(); ttf_skip(16); fd_cur->font_dim[FONTBBOX1_CODE].val = (int) ttf_funit(get_fword()); @@ -697,8 +461,7 @@ void ttf_read_hhea(void) fd_cur->font_dim[DESCENT_CODE].val = (int) ttf_funit(get_fword()); fd_cur->font_dim[ASCENT_CODE].set = true; fd_cur->font_dim[DESCENT_CODE].set = true; - ttf_skip(TTF_FWORD_SIZE + TTF_UFWORD_SIZE + 3 * TTF_FWORD_SIZE + - 8 * TTF_SHORT_SIZE); + ttf_skip(TTF_FWORD_SIZE + TTF_UFWORD_SIZE + 3 * TTF_FWORD_SIZE + 8 * TTF_SHORT_SIZE); nhmtxs = get_ushort(); } @@ -745,55 +508,57 @@ void ttf_read_post(void) post_format = get_fixed(); italic_angle = get_fixed(); int_part = (long) (italic_angle >> 16); - if (int_part > 0x7FFF) { /* a negative number */ + if (int_part > 0x7FFF) { + /*tex a negative number */ int_part = 0x10000 - int_part; sign = -1; } frac_part = (long) (italic_angle % 0x10000); - fd_cur->font_dim[ITALIC_ANGLE_CODE].val = - (int) (sign * ((double) int_part + (double) frac_part * 1.0 / 0x10000)); + fd_cur->font_dim[ITALIC_ANGLE_CODE].val = (int) (sign * ((double) int_part + (double) frac_part * 1.0 / 0x10000)); fd_cur->font_dim[ITALIC_ANGLE_CODE].set = true; - if (glyph_tab == NULL) - return; /* being called from writeotf() */ + if (glyph_tab == NULL) { + /*tex We were being called from |writeotf|. */ + return; + } ttf_skip(2 * TTF_FWORD_SIZE + 5 * TTF_ULONG_SIZE); switch (post_format) { - case 0x10000: - for (glyph = glyph_tab; glyph - glyph_tab < NMACGLYPHS; glyph++) { - glyph->name = (const char *) mac_glyph_names[glyph - glyph_tab]; - glyph->name_index = (TTF_USHORT) (glyph - glyph_tab); - } - break; - case 0x20000: - nnames = get_ushort(); /* some fonts have this value different from nglyphs */ - for (glyph = glyph_tab; glyph - glyph_tab < nnames; glyph++) - glyph->name_index = get_ushort(); - length = - (long) ((long) tab->length - - (long) ((long) ttf_curbyte - (long) tab->offset)); - glyph_name_buf = xtalloc((unsigned) length, char); - for (p = glyph_name_buf; p - glyph_name_buf < length;) { - for (k = get_byte(); k > 0; k--) - *p++ = get_char(); - *p++ = 0; - } - for (glyph = glyph_tab; glyph - glyph_tab < nnames; glyph++) { - if (glyph->name_index < NMACGLYPHS) - glyph->name = mac_glyph_names[glyph->name_index]; - else { - p = glyph_name_buf; - k = glyph->name_index - NMACGLYPHS; - for (; k > 0; k--) - p = strend(p) + 1; - glyph->name = p; + case 0x10000: + for (glyph = glyph_tab; glyph - glyph_tab < NMACGLYPHS; glyph++) { + glyph->name = (const char *) mac_glyph_names[glyph - glyph_tab]; + glyph->name_index = (TTF_USHORT) (glyph - glyph_tab); + } + break; + case 0x20000: + /*tex Some fonts have this value different from |nglyphs|: */ + nnames = get_ushort(); + for (glyph = glyph_tab; glyph - glyph_tab < nnames; glyph++) { + glyph->name_index = get_ushort(); + } + length = (long) ((long) tab->length - (long) ((long) ttf_curbyte - (long) tab->offset)); + glyph_name_buf = xtalloc((unsigned) length, char); + for (p = glyph_name_buf; p - glyph_name_buf < length;) { + for (k = get_byte(); k > 0; k--) + *p++ = get_char(); + *p++ = 0; + } + for (glyph = glyph_tab; glyph - glyph_tab < nnames; glyph++) { + if (glyph->name_index < NMACGLYPHS) + glyph->name = mac_glyph_names[glyph->name_index]; + else { + p = glyph_name_buf; + k = glyph->name_index - NMACGLYPHS; + for (; k > 0; k--) + p = strend(p) + 1; + glyph->name = p; + } + } + break; + default: + formatted_warning("ttf font", "unsupported format '%.8X' of 'post' table, assuming 3.0", (unsigned int) post_format); + case 0x00030000: + for (glyph = glyph_tab; glyph - glyph_tab < NMACGLYPHS; glyph++) { + glyph->name_index = (TTF_USHORT) (glyph - glyph_tab); } - } - break; - default: - formatted_warning("ttf font", "unsupported format '%.8X' of 'post' table, assuming 3.0", (unsigned int) post_format); - case 0x00030000: - for (glyph = glyph_tab; glyph - glyph_tab < NMACGLYPHS; glyph++) { - glyph->name_index = (TTF_USHORT) (glyph - glyph_tab); - } } } @@ -813,14 +578,17 @@ void otc_read_tabdir(int index) { unsigned long i, num, rem=0; dirtab_entry *tab; - ttf_skip(TTF_FIXED_SIZE); /* ignore TTCTag 'ttcf' */ - ttf_skip(TTF_ULONG_SIZE); /* ignorethe version number */ + /*tex Ignore the tag |ttcf|. */ + ttf_skip(TTF_FIXED_SIZE); + /*tex Ignore the version number. */ + ttf_skip(TTF_ULONG_SIZE); num = get_ulong(); for (i = 0; i < num; i++) { if (i==index) rem = get_ulong(); else ttf_skip(TTF_ULONG_SIZE); } ttf_skip(rem - TTF_FIXED_SIZE - (num+2)*TTF_ULONG_SIZE); - ttf_skip(TTF_FIXED_SIZE); /* ignore the sfnt number */ + /*tex Ignore the |sfnt| number. */ + ttf_skip(TTF_FIXED_SIZE); dir_tab = xtalloc(ntabs = get_ushort(), dirtab_entry); ttf_skip(3 * TTF_USHORT_SIZE); for (tab = dir_tab; tab - dir_tab < ntabs; tab++) { @@ -836,7 +604,8 @@ void ttf_read_tabdir(void) { int i; dirtab_entry *tab; - ttf_skip(TTF_FIXED_SIZE); /* ignore the sfnt number */ + /*tex Ignore the |sfnt| number. */ + ttf_skip(TTF_FIXED_SIZE); dir_tab = xtalloc(ntabs = get_ushort(), dirtab_entry); ttf_skip(3 * TTF_USHORT_SIZE); for (tab = dir_tab; tab - dir_tab < ntabs; tab++) { @@ -848,8 +617,7 @@ void ttf_read_tabdir(void) } } -static ttf_cmap_entry *ttf_read_cmap(char *ttf_name, int pid, int eid, - boolean warn) +static ttf_cmap_entry *ttf_read_cmap(char *ttf_name, int pid, int eid, boolean warn) { seg_entry *seg_tab, *s; TTF_USHORT *glyphId, format, segCount; @@ -858,8 +626,7 @@ static ttf_cmap_entry *ttf_read_cmap(char *ttf_name, int pid, int eid, long n, i, k, length, index; ttf_cmap_entry tmp_e, *p; void **aa; - - /* look up in |ttf_cmap_tree| first, return if found */ + /*tex Look up in |ttf_cmap_tree| first, return if found. */ tmp_e.ttf_name = ttf_name; tmp_e.pid = (TTF_USHORT) pid; tmp_e.eid = (TTF_USHORT) eid; @@ -870,9 +637,8 @@ static ttf_cmap_entry *ttf_read_cmap(char *ttf_name, int pid, int eid, p = (ttf_cmap_entry *) avl_find(ttf_cmap_tree, &tmp_e); if (p != NULL) return p; - - /* not found, have to read it */ - ttf_seek_tab("cmap", TTF_USHORT_SIZE); /* skip the table version number (=0) */ + /*tex It's not found so we have to read it. We skip the table version number (0). */ + ttf_seek_tab("cmap", TTF_USHORT_SIZE); ncmapsubtabs = get_ushort(); cmap_offset = (TTF_ULONG) (ttf_curbyte - 2 * TTF_USHORT_SIZE); cmap_tab = xtalloc(ncmapsubtabs, cmap_entry); @@ -886,36 +652,46 @@ static ttf_cmap_entry *ttf_read_cmap(char *ttf_name, int pid, int eid, if (format == 4) goto read_cmap_format_4; else { - if (warn) + if (warn) { formatted_warning("ttf font", "cmap format %i unsupported", format); + } return NULL; } } } - if (warn) + if (warn) { formatted_warning("ttf font", "cannot find cmap subtable for (pid,eid) = (%i,%i)", pid, eid); + } return NULL; + /*tex We jump here: */ read_cmap_format_4: - /* initialize the new entry */ + /*tex Initialize the new entry. */ p = new_ttf_cmap_entry(); p->ttf_name = xstrdup(ttf_name); p->pid = (TTF_USHORT) pid; p->eid = (TTF_USHORT) eid; p->table = xtalloc(0x10000, long); - for (i = 0; i < 0x10000; ++i) - p->table[i] = -1; /* unassigned yet */ - - /* read the subtable */ - length = get_ushort(); /* length of subtable */ - (void) get_ushort(); /* skip the version number */ + for (i = 0; i < 0x10000; ++i) { + /*tex Yet unassigned: */ + p->table[i] = -1; + } + /*tex Read the subtable. */ + /*tex length of subtable */ + length = get_ushort(); + /*tex skip the version number */ + (void) get_ushort(); segCount = get_ushort() / 2; - (void) get_ushort(); /* skip searchRange */ - (void) get_ushort(); /* skip entrySelector */ - (void) get_ushort(); /* skip rangeShift */ + /*tex skip searchRange */ + (void) get_ushort(); + /*tex skip entrySelector */ + (void) get_ushort(); + /*tex skip rangeShift */ + (void) get_ushort(); seg_tab = xtalloc(segCount, seg_entry); for (s = seg_tab; s - seg_tab < segCount; s++) s->endCode = get_ushort(); - (void) get_ushort(); /* skip reversedPad */ + /*tex skip reversedPad */ + (void) get_ushort(); for (s = seg_tab; s - seg_tab < segCount; s++) s->startCode = get_ushort(); for (s = seg_tab; s - seg_tab < segCount; s++) @@ -923,7 +699,8 @@ static ttf_cmap_entry *ttf_read_cmap(char *ttf_name, int pid, int eid, for (s = seg_tab; s - seg_tab < segCount; s++) s->idRangeOffset = get_ushort(); length -= 8 * TTF_USHORT_SIZE + 4 * segCount * TTF_USHORT_SIZE; - n = length / TTF_USHORT_SIZE; /* number of glyphID's */ + /*tex number of glyphID's */ + n = length / TTF_USHORT_SIZE; glyphId = xtalloc((unsigned) n, TTF_USHORT); for (i = 0; i < n; i++) glyphId[i] = get_ushort(); @@ -935,9 +712,7 @@ static ttf_cmap_entry *ttf_read_cmap(char *ttf_name, int pid, int eid, if (s->idRangeOffset == 0) index = (s->idDelta + i) & 0xFFFF; else { - k = (i - s->startCode) + s->idRangeOffset / 2 + - (s - seg_tab) - segCount; - assert(k >= 0 && k < n); + k = (i - s->startCode) + s->idRangeOffset / 2 + (s - seg_tab) - segCount; index = glyphId[k]; if (index != 0) index = (index + s->idDelta) & 0xFFFF; @@ -958,12 +733,12 @@ static ttf_cmap_entry *ttf_read_cmap(char *ttf_name, int pid, int eid, xfree(seg_tab); xfree(glyphId); aa = avl_probe(ttf_cmap_tree, p); - assert(aa != NULL); + if (aa == NULL) { + /*tex Is this a problem? */ + } return p; } -@ -@c static void ttf_read_font(void) { ttf_read_tabdir(); @@ -995,7 +770,6 @@ static void ttf_reset_chksm(PDF pdf, dirtab_entry * tab) formatted_warning("ttf font","offset of `%4.4s' is not a multiple of 4", tab->tag); } - static void ttf_set_chksm(PDF pdf, dirtab_entry * tab) { tab->length = (TTF_ULONG) ttf_offset() - tab->offset; @@ -1012,17 +786,17 @@ static void ttf_copytab(PDF pdf, const char *name) ttf_set_chksm(pdf, tab); } -@ -@c -#define BYTE_ENCODING_LENGTH \ - ((256)*TTF_BYTE_SIZE + 3*TTF_USHORT_SIZE) +#define BYTE_ENCODING_LENGTH ((256)*TTF_BYTE_SIZE + 3*TTF_USHORT_SIZE) static void ttf_byte_encoding(PDF pdf) { ttfenc_entry *e; - (void) put_ushort(0); /* format number (0: byte encoding table) */ - (void) put_ushort(BYTE_ENCODING_LENGTH); /* length of table */ - (void) put_ushort(0); /* version number */ + /*tex Format number (0: byte encoding table) */ + (void) put_ushort(0); + /*tex The length of the table */ + (void) put_ushort(BYTE_ENCODING_LENGTH); + /*tex The version number */ + (void) put_ushort(0); for (e = ttfenc_tab; e - ttfenc_tab < 256; e++) if (e->newindex < 256) { put_byte(e->newindex); @@ -1031,67 +805,87 @@ static void ttf_byte_encoding(PDF pdf) formatted_warning("ttf font", "glyph '%s' has been mapped to '%s' in 'ttf_byte_encoding' cmap table", e->name, notdef); - put_byte(0); /* notdef */ + /*tex |.notdef|: */ + put_byte(0); } } -@ -@c #define TRIMMED_TABLE_MAP_LENGTH (TTF_USHORT_SIZE*(5 + (256))) static void ttf_trimmed_table_map(PDF pdf) { ttfenc_entry *e; - (void) put_ushort(6); /* format number (6): trimmed table mapping */ + /*tex format number 6: trimmed table mapping */ + (void) put_ushort(6); (void) put_ushort(TRIMMED_TABLE_MAP_LENGTH); - (void) put_ushort(0); /* version number (0) */ - (void) put_ushort(0); /* first character code */ - (void) put_ushort(256); /* number of character code in table */ - for (e = ttfenc_tab; e - ttfenc_tab < 256; e++) + /*tex version number 0 */ + (void) put_ushort(0); + /*tex first character code */ + (void) put_ushort(0); + /*tex number of character code in table: */ + (void) put_ushort(256); + for (e = ttfenc_tab; e - ttfenc_tab < 256; e++) { (void) put_ushort(e->newindex); + } } -@ -@c #define SEG_MAP_DELTA_LENGTH ((16 + (256))*TTF_USHORT_SIZE) static void ttf_seg_map_delta(PDF pdf) { ttfenc_entry *e; - (void) put_ushort(4); /* format number (4: segment mapping to delta values) */ + /*tex format number (4: segment mapping to delta values) */ + (void) put_ushort(4); (void) put_ushort(SEG_MAP_DELTA_LENGTH); - (void) put_ushort(0); /* version number */ - (void) put_ushort(4); /* 2*segCount */ - (void) put_ushort(4); /* searchRange */ - (void) put_ushort(1); /* entrySelector */ - (void) put_ushort(0); /* rangeShift */ - (void) put_ushort(0xF0FF); /* endCount[0] */ - (void) put_ushort(0xFFFF); /* endCount[1] */ - (void) put_ushort(0); /* reversedPad */ - (void) put_ushort(0xF000); /* startCount[0] */ - (void) put_ushort(0xFFFF); /* startCount[1] */ - (void) put_ushort(0); /* idDelta[0] */ - (void) put_ushort(1); /* idDelta[1] */ - (void) put_ushort(2 * TTF_USHORT_SIZE); /* idRangeOffset[0] */ - (void) put_ushort(0); /* idRangeOffset[1] */ - for (e = ttfenc_tab; e - ttfenc_tab < 256; e++) + /*tex version number */ + (void) put_ushort(0); + /*tex 2*segCount */ + (void) put_ushort(4); + /*tex searchRange */ + (void) put_ushort(4); + /*tex entrySelector */ + (void) put_ushort(1); + /*tex rangeShift */ + (void) put_ushort(0); + /*tex endCount[0] */ + (void) put_ushort(0xF0FF); + /*tex endCount[1] */ + (void) put_ushort(0xFFFF); + /*tex reversedPad */ + (void) put_ushort(0); + /*tex startCount[0] */ + (void) put_ushort(0xF000); + /*tex startCount[1] */ + (void) put_ushort(0xFFFF); + /*tex idDelta[0] */ + (void) put_ushort(0); + /*tex idDelta[1] */ + (void) put_ushort(1); + /*tex idRangeOffset[0] */ + (void) put_ushort(2 * TTF_USHORT_SIZE); + /*tex idRangeOffset[1] */ + (void) put_ushort(0); + for (e = ttfenc_tab; e - ttfenc_tab < 256; e++) { (void) put_ushort(e->newindex); + } } -@ -@c #define CMAP_ENTRY_LENGTH (2*TTF_USHORT_SIZE + TTF_ULONG_SIZE) static void ttf_select_cmap(void) { - assert(sizeof(new_cmap_tab) <= NEW_CMAP_SIZE * sizeof(cmap_entry)); - new_cmap_tab[0].platform_id = 1; /* Macintosh */ - new_cmap_tab[0].encoding_id = 0; /* Symbol; ignore code page */ - new_cmap_tab[0].format = (TTF_USHORT) (new_glyphs_count < 256 ? 0 /* byte encoding */ - : 6); /* trimmed table mapping */ - new_cmap_tab[1].platform_id = 3; /* Microsoft */ - new_cmap_tab[1].encoding_id = 0; /* Symbol; ignore code page */ - new_cmap_tab[1].format = 4; /* segment mapping to delta */ + /*tex Macintosh */ + new_cmap_tab[0].platform_id = 1; + /*tex Symbol; ignore code page */ + new_cmap_tab[0].encoding_id = 0; + /*tex byte encoding (0) or trimmed table mapping (6) */ + new_cmap_tab[0].format = (TTF_USHORT) (new_glyphs_count < 256 ? 0 : 6); + /*tex Microsoft */ + new_cmap_tab[1].platform_id = 3; + /*tex Symbol; ignore code page */ + new_cmap_tab[1].encoding_id = 0; + /*tex segment mapping to delta */ + new_cmap_tab[1].format = 4; } static void ttf_write_cmap(PDF pdf) @@ -1101,23 +895,25 @@ static void ttf_write_cmap(PDF pdf) dirtab_entry *tab = ttf_name_lookup("cmap", true); ttf_select_cmap(); ttf_reset_chksm(pdf, tab); - (void) put_ushort(0); /* table version number (0) */ - (void) put_ushort(NEW_CMAP_SIZE); /* number of encoding tables */ + /*tex Table version number 0. */ + (void) put_ushort(0); + /*tex Number of encoding tables. */ + (void) put_ushort(NEW_CMAP_SIZE); offset = 2 * TTF_USHORT_SIZE + NEW_CMAP_SIZE * CMAP_ENTRY_LENGTH; for (ce = new_cmap_tab; ce - new_cmap_tab < NEW_CMAP_SIZE; ce++) { ce->offset = (TTF_ULONG) offset; switch (ce->format) { - case 0: - offset += BYTE_ENCODING_LENGTH; - break; - case 4: - offset += SEG_MAP_DELTA_LENGTH; - break; - case 6: - offset += TRIMMED_TABLE_MAP_LENGTH; - break; - default: - normal_error("ttf font","invalid format (it should not have happened)"); + case 0: + offset += BYTE_ENCODING_LENGTH; + break; + case 4: + offset += SEG_MAP_DELTA_LENGTH; + break; + case 6: + offset += TRIMMED_TABLE_MAP_LENGTH; + break; + default: + normal_error("ttf font","invalid format (it should not have happened)"); } (void) put_ushort(ce->platform_id); (void) put_ushort(ce->encoding_id); @@ -1125,27 +921,24 @@ static void ttf_write_cmap(PDF pdf) } for (ce = new_cmap_tab; ce - new_cmap_tab < NEW_CMAP_SIZE; ce++) { switch (ce->format) { - case 0: - ttf_byte_encoding(pdf); - break; - case 4: - ttf_seg_map_delta(pdf); - break; - case 6: - ttf_trimmed_table_map(pdf); - break; - } + case 0: + ttf_byte_encoding(pdf); + break; + case 4: + ttf_seg_map_delta(pdf); + break; + case 6: + ttf_trimmed_table_map(pdf); + break; + } } ttf_set_chksm(pdf, tab); } -@ -@c static int prepend_subset_tags(int index, char *p) { boolean is_unicode; int i; - assert(index >= 0 && index < name_record_num && fd_cur->subset_tag != NULL); is_unicode = (name_tab[index].platform_id == 3); if (is_unicode) { for (i = 0; i < 6; ++i) { @@ -1174,10 +967,12 @@ static void ttf_write_name(PDF pdf) dirtab_entry *tab = ttf_name_lookup("name", true); if (is_subsetted(fd_cur->fm)) { l = 0; - for (i = 0; i < name_record_num; i++) - l += name_tab[i].length + 14; /* maximum lengh of new stogare area */ + for (i = 0; i < name_record_num; i++) { + /*tex Maximum lengh of new stogare area. */ + l += name_tab[i].length + 14; + } new_name_buf = xtalloc((unsigned) l, char); - /* additional space for subset tags */ + /*tex Additional space for subset tags. */ p = new_name_buf; for (i = 0; i < name_record_num; i++) { n = name_tab + i; @@ -1201,10 +996,10 @@ static void ttf_write_name(PDF pdf) new_name_buf_size = name_buf_size; } ttf_reset_chksm(pdf, tab); - (void) put_ushort(0); /* Format selector */ + (void) put_ushort(0); + /*tex Format selector. */ (void) put_ushort(name_record_num); - (void) put_ushort(3 * TTF_USHORT_SIZE + - name_record_num * 6 * TTF_USHORT_SIZE); + (void) put_ushort(3 * TTF_USHORT_SIZE + name_record_num * 6 * TTF_USHORT_SIZE); for (i = 0; i < name_record_num; i++) { (void) put_ushort(name_tab[i].platform_id); (void) put_ushort(name_tab[i].encoding_id); @@ -1220,8 +1015,6 @@ static void ttf_write_name(PDF pdf) xfree(new_name_buf); } -@ -@c static void ttf_write_dirtab(PDF pdf) { dirtab_entry *tab; @@ -1249,7 +1042,7 @@ static void ttf_write_dirtab(PDF pdf) put_ulong((long) tab->length); } } - /* adjust checkSumAdjustment */ + /*tex adjust |checkSumAdjustment| */ tmp_ulong = 0; checksum = 0; for (p = (char *) pdf->fb->data, i = 0; i < (unsigned) save_offset;) { @@ -1270,8 +1063,6 @@ static void ttf_write_dirtab(PDF pdf) ttf_seek_outbuf(save_offset); } -@ -@c static void ttf_write_glyf(PDF pdf) { long *id, k; @@ -1294,9 +1085,9 @@ static void ttf_write_glyf(PDF pdf) if (glyph_tab[idx].newindex < 0) { glyph_tab[idx].newindex = (TTF_SHORT) new_glyphs_count; glyph_index[new_glyphs_count++] = idx; - /* - N.B.: Here we change |new_glyphs_count|, - which appears in the condition of the |for| loop + /*tex + Here we change |new_glyphs_count|, which appears in + the condition of the |for| loop. */ } (void) put_ushort(glyph_tab[idx].newindex); @@ -1314,21 +1105,22 @@ static void ttf_write_glyf(PDF pdf) if (flags & WE_HAVE_INSTRUCTIONS) ttf_ncopy(pdf, copy_ushort()); } else - ttf_ncopy(pdf, (int) - (glyph_tab[*id + 1].offset - glyph_tab[*id].offset - - TTF_USHORT_SIZE - 4 * TTF_FWORD_SIZE)); + ttf_ncopy(pdf, (int) (glyph_tab[*id + 1].offset - glyph_tab[*id].offset - TTF_USHORT_SIZE - 4 * TTF_FWORD_SIZE)); } } last_glyf_offset = (TTF_ULONG) ttf_offset() - (TTF_ULONG) new_glyf_offset; ttf_set_chksm(pdf, tab); } -@ Reindexing glyphs: we append index of used glyphs to |glyph_index| - while going through |ttfenc_tab|. After appending a new entry to - |glyph_index| we set field |newindex| of corresponding entries in both - |glyph_tab| and |ttfenc_tab| to the newly created index. +/*tex + + Reindexing glyphs: we append index of used glyphs to |glyph_index| while + going through |ttfenc_tab|. After appending a new entry to |glyph_index| we + set field |newindex| of corresponding entries in both |glyph_tab| and + |ttfenc_tab| to the newly created index. + +*/ -@c static void ttf_reindex_glyphs(void) { ttfenc_entry *e; @@ -1337,14 +1129,13 @@ static void ttf_reindex_glyphs(void) long *t; ttf_cmap_entry *cmap = NULL; boolean cmap_not_found = false; - for (e = ttfenc_tab; e - ttfenc_tab < 256; e++) { - e->newindex = 0; /* index of ".notdef" glyph */ - - /* handle case of reencoded fonts */ + /*tex The index of the |.notdef| glyph */ + e->newindex = 0; + /*tex Handle the case of reencoded fonts. */ if (e->name == notdef) continue; - /* scan form `index123' */ + /*tex Scan form |index123|. */ if (sscanf(e->name, GLYPH_PREFIX_INDEX "%i", &index) == 1) { if (index >= glyphs_count) { formatted_warning("ttf font","'%s' out of valid range [0..%i)", e->name, glyphs_count); @@ -1353,22 +1144,22 @@ static void ttf_reindex_glyphs(void) glyph = glyph_tab + index; goto append_new_glyph; } - /* scan form `uniABCD' */ + /*tex Scan form |uniABCD|. */ if (sscanf(e->name, GLYPH_PREFIX_UNICODE "%X", &index) == 1) { if (cmap == NULL && !cmap_not_found) { - /* need to read the unicode mapping, ie (pid,eid) = (3,1) or (0,3) */ + /*tex Need to read the \UNICODE\ mapping, i.e. |(pid,eid) = (3,1) or (0,3)|. */ cmap = ttf_read_cmap(fd_cur->fm->ff_name, 3, 1, false); if (cmap == NULL) cmap = ttf_read_cmap(fd_cur->fm->ff_name, 0, 3, false); if (cmap == NULL) { + /*tex Once only. */ normal_warning("ttf font", "no unicode mapping found, all 'uniXXXX' names will be ignored"); - cmap_not_found = true; /* once only */ + cmap_not_found = true; } } if (cmap == NULL) continue; t = cmap->table; - assert(t != NULL); if (t[index] != -1) { if (t[index] >= glyphs_count) { formatted_warning("ttf font", "'%s' is mapped to index %li which is out of valid range [0..%i)", @@ -1382,7 +1173,7 @@ static void ttf_reindex_glyphs(void) continue; } } - /* look up by name */ + /*tex Look up by name: */ for (glyph = glyph_tab; glyph - glyph_tab < glyphs_count; glyph++) if (glyph->name != notdef && strcmp(glyph->name, e->name) == 0) break; @@ -1391,7 +1182,6 @@ static void ttf_reindex_glyphs(void) continue; } append_new_glyph: - assert(glyph > glyph_tab && glyph - glyph_tab < glyphs_count); if (glyph->newindex < 0) { glyph_index[new_glyphs_count] = (short) (glyph - glyph_tab); glyph->newindex = (TTF_SHORT) new_glyphs_count; @@ -1401,28 +1191,42 @@ static void ttf_reindex_glyphs(void) } } -@ To calculate the checkSum for the 'head' table which itself includes the - checkSumAdjustment entry for the entire font, do the following: +/*tex + + To calculate the checkSum for the 'head' table which itself includes the + checkSumAdjustment entry for the entire font, do the following: + + \startitemize + \startitem + Set the checkSumAdjustment to 0. + \stopitem + \startitem + Calculate the checksum for all the tables including the |head| table + and enter that value into the table directory. + \stopitem + \startitem + Calculate the checksum for the entire font. + \stopitem + \startitem + Subtract that value from the hex value B1B0AFBA. + \stopitem + \startitem + Store the result in checkSumAdjustment. + \stopitem + \startitemize + + The checkSum for the 'head table which includes the checkSumAdjustment entry + for the entire font is now incorrect. That is not a problem. Do not change + it. An application attempting to verify that the 'head' table has not changed + should calculate the checkSum for that table by not including the + checkSumAdjustment value, and compare the result with the entry in the table + directory. + + The table directory also includes the offset of the associated tagged table + from the beginning of the font file and the length of that table. + +*/ - \item Set the checkSumAdjustment to 0. - \item Calculate the checksum for all the tables including the 'head' table - and enter that value into the table directory. - \item Calculate the checksum for the entire font. - \item Subtract that value from the hex value B1B0AFBA. - \item Store the result in checkSumAdjustment. - - The checkSum for the 'head table which includes the checkSumAdjustment - entry for the entire font is now incorrect. That is not a problem. Do not - change it. An application attempting to verify that the 'head' table has - not changed should calculate the checkSum for that table by not including - the checkSumAdjustment value, and compare the result with the entry in the - table directory. - - The table directory also includes the offset of the associated tagged - table from the beginning of the font file and the length of that table. - - -@c static void ttf_write_head(PDF pdf) { dirtab_entry *tab; @@ -1431,9 +1235,9 @@ static void ttf_write_head(PDF pdf) ttf_ncopy(pdf, 2 * TTF_FIXED_SIZE); checkSumAdjustment_offset = (TTF_ULONG) ttf_offset(); put_ulong(0); - ttf_skip(TTF_ULONG_SIZE); /* skip checkSumAdjustment */ - ttf_ncopy(pdf, TTF_ULONG_SIZE + 2 * TTF_USHORT_SIZE + 16 + - 4 * TTF_FWORD_SIZE + 2 * TTF_USHORT_SIZE + TTF_SHORT_SIZE); + /*tex skip |checkSumAdjustment| */ + ttf_skip(TTF_ULONG_SIZE); + ttf_ncopy(pdf, TTF_ULONG_SIZE + 2 * TTF_USHORT_SIZE + 16 + 4 * TTF_FWORD_SIZE + 2 * TTF_USHORT_SIZE + TTF_SHORT_SIZE); if (is_subsetted(fd_cur->fm)) { (void) put_short(loca_format); (void) put_short(0); @@ -1442,21 +1246,16 @@ static void ttf_write_head(PDF pdf) ttf_set_chksm(pdf, tab); } -@ -@c static void ttf_write_hhea(PDF pdf) { dirtab_entry *tab; tab = ttf_seek_tab("hhea", 0); ttf_reset_chksm(pdf, tab); - ttf_ncopy(pdf, TTF_FIXED_SIZE + 3 * TTF_FWORD_SIZE + TTF_UFWORD_SIZE + - 3 * TTF_FWORD_SIZE + 8 * TTF_SHORT_SIZE); + ttf_ncopy(pdf, TTF_FIXED_SIZE + 3 * TTF_FWORD_SIZE + TTF_UFWORD_SIZE + 3 * TTF_FWORD_SIZE + 8 * TTF_SHORT_SIZE); (void) put_ushort(new_glyphs_count); ttf_set_chksm(pdf, tab); } -@ -@c static void ttf_write_htmx(PDF pdf) { long *id; @@ -1469,8 +1268,6 @@ static void ttf_write_htmx(PDF pdf) ttf_set_chksm(pdf, tab); } -@ -@c static void ttf_write_loca(PDF pdf) { long *id; @@ -1497,8 +1294,6 @@ static void ttf_write_loca(PDF pdf) ttf_set_chksm(pdf, tab); } -@ -@c static void ttf_write_mapx(PDF pdf) { dirtab_entry *tab = ttf_seek_tab("maxp", TTF_FIXED_SIZE + TTF_USHORT_SIZE); @@ -1509,37 +1304,41 @@ static void ttf_write_mapx(PDF pdf) ttf_set_chksm(pdf, tab); } -@ -@c static void ttf_write_OS2(PDF pdf) { dirtab_entry *tab = ttf_seek_tab("OS/2", 0); TTF_USHORT version; ttf_reset_chksm(pdf, tab); version = get_ushort(); - if (version > 3) + if (version > 3) { formatted_error("ttf font","unknown version '%.4X' of OS/2 table", version); - (void) put_ushort(0x0001); /* fix version to 1 */ - ttf_ncopy(pdf, - 2 * TTF_USHORT_SIZE + 13 * TTF_SHORT_SIZE + 10 * TTF_BYTE_SIZE); - ttf_skip(4 * TTF_ULONG_SIZE); /* ulUnicodeRange 1--4 */ - put_ulong(0x00000003); /* Basic Latin + Latin-1 Supplement (0x0000--0x00FF) */ - put_ulong(0x10000000); /* Private Use (0xE000--0xF8FF) */ + } + /*tex fix version to 1 */ + (void) put_ushort(0x0001); + ttf_ncopy(pdf,2 * TTF_USHORT_SIZE + 13 * TTF_SHORT_SIZE + 10 * TTF_BYTE_SIZE); + /*tex |ulUnicodeRange| 1--4 */ + ttf_skip(4 * TTF_ULONG_SIZE); + /*tex Basic Latin + Latin-1 Supplement (0x0000--0x00FF) */ + put_ulong(0x00000003); + /*tex Private Use (0xE000--0xF8FF) */ + put_ulong(0x10000000); put_ulong(0x00000000); put_ulong(0x00000000); - ttf_ncopy(pdf, 4 * TTF_CHAR_SIZE + TTF_USHORT_SIZE); /* achVendID + fsSelection */ + /*tex |achVendID| + |fsSelection| */ + ttf_ncopy(pdf, 4 * TTF_CHAR_SIZE + TTF_USHORT_SIZE); ttf_skip(2 * TTF_USHORT_SIZE); - (void) put_ushort(0x0000); /* usFirstCharIndex */ - (void) put_ushort(0xF0FF); /* usLastCharIndex */ + /*tex |usFirstCharIndex| */ + (void) put_ushort(0x0000); + /*tex |usLastCharIndex| */ + (void) put_ushort(0xF0FF); ttf_ncopy(pdf, 5 * TTF_USHORT_SIZE); - /* for version 0 the OS/2 table ends here, the rest is for version 1 */ - put_ulong(0x80000000); /* Symbol Character Set---don't use any code page */ + /*tex For version 0 the OS/2 table ends here, the rest is for version 1. */ + /*tex Symbol Character Set: don't use any code page */ + put_ulong(0x80000000); put_ulong(0x00000000); ttf_set_chksm(pdf, tab); } -@ -@c static boolean unsafe_name(const char *s) { const char **p; @@ -1559,12 +1358,10 @@ static void ttf_write_post(PDF pdf) ttf_reset_chksm(pdf, tab); if (!fd_cur->write_ttf_glyph_names || post_format == 0x00030000) { put_fixed(0x00030000); - ttf_ncopy(pdf, - TTF_FIXED_SIZE + 2 * TTF_FWORD_SIZE + 5 * TTF_ULONG_SIZE); + ttf_ncopy(pdf, TTF_FIXED_SIZE + 2 * TTF_FWORD_SIZE + 5 * TTF_ULONG_SIZE); } else { put_fixed(0x00020000); - ttf_ncopy(pdf, - TTF_FIXED_SIZE + 2 * TTF_FWORD_SIZE + 5 * TTF_ULONG_SIZE); + ttf_ncopy(pdf, TTF_FIXED_SIZE + 2 * TTF_FWORD_SIZE + 5 * TTF_ULONG_SIZE); (void) put_ushort(new_glyphs_count); k = 0; for (id = glyph_index; id - glyph_index < new_glyphs_count; id++) { @@ -1587,22 +1384,23 @@ static void ttf_write_post(PDF pdf) ttf_set_chksm(pdf, tab); } -@ -@c static void ttf_init_font(PDF pdf, int n) { int i, k; for (i = 1, k = 0; i <= n; i <<= 1, k++); - put_fixed(0x00010000); /* font version */ - (void) put_ushort(n); /* number of tables */ - (void) put_ushort(i << 3); /* search range */ - (void) put_ushort(k - 1); /* entry selector */ - (void) put_ushort((n << 4) - (i << 3)); /* range shift */ + /*tex font version */ + put_fixed(0x00010000); + /*tex number of tables */ + (void) put_ushort(n); + /*tex search range */ + (void) put_ushort(i << 3); + /*tex entry selector */ + (void) put_ushort(k - 1); + /*tex range shift */ + (void) put_ushort((n << 4) - (i << 3)); ttf_seek_outbuf(TABDIR_OFF + n * 4 * TTF_ULONG_SIZE); } -@ -@c static void ttf_subset_font(PDF pdf) { ttf_init_font(pdf, new_ntabs); @@ -1628,8 +1426,6 @@ static void ttf_subset_font(PDF pdf) ttf_write_dirtab(pdf); } -@ -@c static void ttf_copy_font(PDF pdf) { dirtab_entry *tab; @@ -1643,33 +1439,25 @@ static void ttf_copy_font(PDF pdf) ttf_write_dirtab(pdf); } -@ -@c void writettf(PDF pdf, fd_entry * fd) { int callback_id; int file_opened = 0; - fd_cur = fd; /* |fd_cur| is global inside \.{writettf.w} */ - assert(fd_cur->fm != NULL); - assert(is_truetype(fd_cur->fm)); - assert(is_included(fd_cur->fm)); - + /* The next one is global inside |writettf.c| */ + fd_cur = fd; if (is_subsetted(fd_cur->fm) && (fd_cur->fe == NULL)) { normal_error("ttf font","subset must be a reencoded font"); } ttf_curbyte = 0; ttf_size = 0; - - cur_file_name = - luatex_find_file(fd_cur->fm->ff_name, find_truetype_file_callback); + cur_file_name = luatex_find_file(fd_cur->fm->ff_name, find_truetype_file_callback); if (cur_file_name == NULL) { formatted_error("ttf font","cannot find font file for reading '%s'", fd_cur->fm->ff_name); } callback_id = callback_defined(read_truetype_file_callback); if (callback_id > 0) { - if (run_callback(callback_id, "S->bSd", cur_file_name, - &file_opened, &ttf_buffer, &ttf_size) && - file_opened && ttf_size > 0) { + if (run_callback(callback_id, "S->bSd", cur_file_name, &file_opened, &ttf_buffer, &ttf_size) && file_opened && ttf_size > 0) { + /* We're okay. */ } else { formatted_error("ttf font","cannot open font file for reading '%s'", cur_file_name); } @@ -1696,7 +1484,6 @@ void writettf(PDF pdf, fd_entry * fd) name_tab = NULL; name_buf = NULL; ttf_read_font(); - pdf_save_offset(pdf); pdf_flush(pdf); if (is_subsetted(fd_cur->fm)) { @@ -1705,7 +1492,6 @@ void writettf(PDF pdf, fd_entry * fd) } else ttf_copy_font(pdf); ttf_length = ttf_offset(); - xfree(dir_tab); xfree(glyph_tab); xfree(glyph_index); @@ -1732,7 +1518,7 @@ static void do_writeotf(PDF pdf, fd_entry * fd) if (tracefilenames) tex_printf("<<%s", cur_file_name); ttf_read_tabdir(); - /* read font parameters */ + /*tex Read teh font parameters. */ if (ttf_name_lookup("head", false) != NULL) ttf_read_head(); if (ttf_name_lookup("hhea", false) != NULL) @@ -1741,10 +1527,10 @@ static void do_writeotf(PDF pdf, fd_entry * fd) ttf_read_pclt(); if (ttf_name_lookup("post", false) != NULL) ttf_read_post(); - /* copy font file */ - if (ttf_name_lookup("CFF2", false) != NULL) /* HH */ - tab = ttf_seek_tab("CFF2", 0); /* HH */ - else /* HH */ + /*tex Copy the font file: */ + if (ttf_name_lookup("CFF2", false) != NULL) + tab = ttf_seek_tab("CFF2", 0); + else tab = ttf_seek_tab("CFF ", 0); for (i = (long) tab->length; i > 0; i--) { copy_char(); @@ -1754,30 +1540,21 @@ static void do_writeotf(PDF pdf, fd_entry * fd) tex_printf(">>"); } -@ -@c void writeotf(PDF pdf, fd_entry * fd) { int callback_id; int file_opened = 0; - fd_cur = fd; - assert(fd_cur->fm != NULL); - assert(is_opentype(fd_cur->fm)); - assert(is_included(fd_cur->fm)); - ttf_curbyte = 0; ttf_size = 0; - cur_file_name = - luatex_find_file(fd_cur->fm->ff_name, find_opentype_file_callback); + cur_file_name = luatex_find_file(fd_cur->fm->ff_name, find_opentype_file_callback); if (cur_file_name == NULL) { formatted_error("otf font","cannot find font file for reading '%s'", fd_cur->fm->ff_name); } callback_id = callback_defined(read_opentype_file_callback); if (callback_id > 0) { - if (run_callback(callback_id, "S->bSd", cur_file_name, - &file_opened, &ttf_buffer, &ttf_size) && - file_opened && ttf_size > 0) { + if (run_callback(callback_id, "S->bSd", cur_file_name, &file_opened, &ttf_buffer, &ttf_size) && file_opened && ttf_size > 0) { + /*tex We're okay. */ } else { formatted_error("otf font","cannot open font file for reading '%s'", cur_file_name); } @@ -1788,7 +1565,6 @@ void writeotf(PDF pdf, fd_entry * fd) ttf_read_file(); ttf_close(); } - fd_cur->ff_found = true; do_writeotf(pdf, fd); xfree(ttf_buffer); diff --git a/Build/source/texk/web2c/luatexdir/font/writetype0.w b/Build/source/texk/web2c/luatexdir/font/writetype0.c index ebf4be66723..7a81d58c992 100644 --- a/Build/source/texk/web2c/luatexdir/font/writetype0.w +++ b/Build/source/texk/web2c/luatexdir/font/writetype0.c @@ -1,29 +1,34 @@ -% writetype0.w -% -% Copyright 2006-2008 Taco Hoekwater <taco@@luatex.org> -% -% This file is part of LuaTeX. -% -% LuaTeX 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. -% -% LuaTeX 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 Lesser General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License along -% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. +/* -@ @c +Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> + +This file is part of LuaTeX. + +LuaTeX 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. + +LuaTeX 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU General Public License along +with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +*/ #include "ptexlib.h" #include "font/writettf.h" #include "font/writecff.h" -@ @c +/*tex + + Here we also support the newer CFF2 specification, + +*/ + extern unsigned char *ttf_buffer; void writetype0(PDF pdf, fd_entry * fd) @@ -34,15 +39,13 @@ void writetype0(PDF pdf, fd_entry * fd) dirtab_entry *tab; cff_font *cff; sfnt *sfont; - dir_tab = NULL; glyph_tab = NULL; - - fd_cur = fd; /* |fd_cur| is global inside \.{writettf.w} */ + /*tex |fd_cur| is global inside |writettf.c| */ + fd_cur = fd; assert(fd_cur->fm != NULL); assert(is_opentype(fd_cur->fm) || is_truetype(fd_cur->fm)); assert(is_included(fd_cur->fm)); - ttf_curbyte = 0; ttf_size = 0; cur_file_name = @@ -69,9 +72,7 @@ void writetype0(PDF pdf, fd_entry * fd) ttf_read_file(); ttf_close(); } - fd_cur->ff_found = true; - sfont = sfnt_open(ttf_buffer, ttf_size); if (sfont->type == SFNT_TYPE_TTC) i = ff_get_ttc_index(fd->fm->ff_name, fd->fm->ps_name); @@ -86,7 +87,7 @@ void writetype0(PDF pdf, fd_entry * fd) else ttf_read_tabdir(); sfnt_close(sfont); - /* read font parameters */ + /*tex Read font parameters: */ if (ttf_name_lookup("head", false) != NULL) ttf_read_head(); if (ttf_name_lookup("hhea", false) != NULL) @@ -95,32 +96,25 @@ void writetype0(PDF pdf, fd_entry * fd) ttf_read_pclt(); if (ttf_name_lookup("post", false) != NULL) ttf_read_post(); - - /* copy font file */ - if (ttf_name_lookup("CFF2", false) != NULL) /* HH */ - tab = ttf_seek_tab("CFF2", 0); /* HH */ - else /* HH */ + /*tex Copy font file, including the newer variant: */ + if (ttf_name_lookup("CFF2", false) != NULL) + tab = ttf_seek_tab("CFF2", 0); + else tab = ttf_seek_tab("CFF ", 0); - - /* TODO the next 0 is a subfont index */ cff = read_cff(ttf_buffer + ttf_curbyte, (long) tab->length, 0); if (!is_subsetted(fd_cur->fm)) { - /* not subsetted, just do a copy */ + /*tex not subsetted, copy: */ for (i = (long) tab->length; i > 0; i--) strbuf_putchar(pdf->fb, (unsigned char) ttf_getnum(1)); } else { if (cff != NULL) { if (cff_is_cidfont(cff)) { write_cid_cff(pdf, cff, fd_cur); -#if 0 - for (i = tab->length; i > 0; i--) - strbuf_putchar(pdf->fb, (unsigned char) ttf_getnum(1)); -#endif } else { write_cff(pdf, cff, fd_cur); } } else { - /* not understood, just do a copy */ + /*tex Just copy: */ for (i = (long) tab->length; i > 0; i--) strbuf_putchar(pdf->fb, (unsigned char) ttf_getnum(1)); } diff --git a/Build/source/texk/web2c/luatexdir/font/writetype2.w b/Build/source/texk/web2c/luatexdir/font/writetype2.c index 81aefb1fb69..b8a74609007 100644 --- a/Build/source/texk/web2c/luatexdir/font/writetype2.w +++ b/Build/source/texk/web2c/luatexdir/font/writetype2.c @@ -1,24 +1,23 @@ -% writetype2.w -% -% Copyright 2006-2012 Taco Hoekwater <taco@@luatex.org> -% -% This file is part of LuaTeX. -% -% LuaTeX 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. -% -% LuaTeX 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 Lesser General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License along -% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. - -@ @c +/* +Copyright 2006-2012 Taco Hoekwater <taco@luatex.org> + +This file is part of LuaTeX. + +LuaTeX 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. + +LuaTeX 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU General Public License along +with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +*/ #include "ptexlib.h" #include "font/writettf.h" @@ -28,15 +27,22 @@ #include "font/sfnt.h" #include "font/tt_glyf.h" -@ forward declaration -@c +/*tex + + Forward declarations + +*/ + boolean make_tt_subset(PDF pdf, fd_entry * fd, unsigned char *buff, int buflen); -@ @c unsigned long cidtogid_obj = 0; -@ low-level helpers -@c +/*tex + + Low-level helpers (a weird place): + +*/ + #define test_loc(l) \ if ((f->loc + l) > f->buflen) { \ normal_error("type 2","the file ended prematurely"); \ @@ -96,55 +102,23 @@ int do_sfnt_read(unsigned char *dest, int len, sfnt * f) return len; } -pdf_obj *pdf_new_stream(void) -{ - pdf_obj *stream = xmalloc(sizeof(pdf_obj)); - stream->length = 0; - stream->data = NULL; - return stream; -} +/*tex -void pdf_add_stream(pdf_obj * stream, unsigned char *buf, long len) -{ - int i; - assert(stream != NULL); - if (stream->data == NULL) { - stream->data = xmalloc((unsigned) len); - } else { - stream->data = - xrealloc(stream->data, (unsigned) len + (unsigned) stream->length); - } - for (i = 0; i < len; i++) { - *(stream->data + stream->length + i) = *(buf + i); - } - stream->length += (unsigned) len; -} + The main function: -void pdf_release_obj(pdf_obj * stream) -{ - if (stream != NULL) { - if (stream->data != NULL) { - xfree(stream->data); - } - xfree(stream); - } -} +*/ -@ The main function. -@c boolean writetype2(PDF pdf, fd_entry * fd) { int callback_id; int file_opened = 0; boolean ret; - glyph_tab = NULL; - - fd_cur = fd; /* |fd_cur| is global inside \.{writettf.w} */ + /*tex |fd_cur| is global inside |writettf.c| */ + fd_cur = fd; assert(fd_cur->fm != NULL); assert(is_truetype(fd_cur->fm)); assert(is_included(fd_cur->fm)); - ttf_curbyte = 0; ttf_size = 0; cur_file_name = @@ -167,20 +141,13 @@ boolean writetype2(PDF pdf, fd_entry * fd) ttf_read_file(); ttf_close(); } - fd_cur->ff_found = true; - if (is_subsetted(fd_cur->fm)) report_start_file(filetype_subset,cur_file_name); else report_start_file(filetype_font,cur_file_name); - - /* here is the real work */ - + /*tex Here is the real work done: */ ret = make_tt_subset(pdf, fd, ttf_buffer, ttf_size); -#if 0 - xfree (dir_tab); -#endif xfree(ttf_buffer); if (is_subsetted(fd_cur->fm)) report_stop_file(filetype_subset); @@ -190,72 +157,69 @@ boolean writetype2(PDF pdf, fd_entry * fd) return ret; } -@ PDF viewer applications use following tables (CIDFontType 2) - -\.{head, hhea, loca, maxp, glyf, hmtx, fpgm, cvt\_, prep} - -\rightline{from PDF Ref. v.1.3, 2nd ed.} +/*tex - The \.{fpgm}, \.{cvt\_} and \.{prep} tables appears only when TrueType instructions - requires them. Those tables must be preserved if they exist. - We use |must_exist| flag to indicate `preserve it if present' - and to make sure not to cause an error when it does not exist. + The \PDF\ viewer applications use following tables for CIDFontType 2: |head|, + |hhea|, |loca|, |maxp|, |glyf|, |hmtx|, |fpgm|, |cvt| and |prep|. According + to PDF Ref. v.1.3, 2nd ed. The |fpgm\, |cvt| and |prep| tables appears only + when TrueType instructions requires them. Those tables must be preserved if + they exist. We use |must_exist| flag to indicate `preserve it if present' and + to make sure not to cause an error when it does not exist. The |post\ and + |name| tables must exist in ordinary TrueType font file, but when a TrueType + font is converted to CIDFontType 2 font, those tables are no longer required. + The |OS/2| table (required for TrueType font for Windows and OS/2) contains + liscencing information, but PDF viewers seems not using them. The |name| + table as been added added too (see comments in |writettf.c|. - \.{post} and \.{name} table must exist in ordinary TrueType font file, - but when a TrueType font is converted to CIDFontType 2 font, those tables - are no longer required. +*/ - The OS/2 table (required for TrueType font for Windows and OS/2) contains - liscencing information, but PDF viewers seems not using them. - - The \.{name} table added. See comments in \.{writettf.w}. - -@c static struct { const char *name; int must_exist; -} required_table[] = { - { - "OS/2", 0}, { - "cmap", 0}, { - "head", 1}, { - "hhea", 1}, { - "loca", 1}, { - "maxp", 0}, { - "name", 1}, { - "glyf", 1}, { - "hmtx", 1}, { - "fpgm", 0}, { - "cvt ", 0}, { - "prep", 0}, { - NULL, 0} -}; +} +required_table[] = { + { "OS/2", 0 }, + { "cmap", 0 }, + { "head", 1 }, + { "hhea", 1 }, + { "loca", 1 }, + { "maxp", 0 }, + { "name", 1 }, + { "glyf", 1 }, + { "hmtx", 1 }, + { "fpgm", 0 }, + { "cvt ", 0 }, + { "prep", 0 }, + { NULL, 0 } +}; unsigned long ttc_read_offset(sfnt * sfont, int ttc_idx, fd_entry * fd) { - /*ULONG version;*/ unsigned long offset = 0; unsigned long num_dirs = 0; - - sfnt_seek_set(sfont, 4); /* skip version tag */ - - /*version = */(void)sfnt_get_ulong(sfont); + /*tex Skip the |ULONG| version tag: */ + sfnt_seek_set(sfont, 4); + /* version = */ (void)sfnt_get_ulong(sfont); num_dirs = sfnt_get_ulong(sfont); if (ttc_idx < 0 || ttc_idx > (int) (num_dirs - 1)) { - formatted_error("type 2","invalid TTC index number %i (0..%i), using index 0 for font %s", + formatted_error("type 2", + "invalid TTC index number %i (0..%i), using index 0 for font %s", ttc_idx,(int) (num_dirs - 1),(fd->fm->ps_name ? fd->fm->ps_name : "")); return 0 ; } sfnt_seek_set(sfont, 12 + ttc_idx * 4); offset = sfnt_get_ulong(sfont); - return offset; } -@ Creating the subset. -@c +/*tex + + Creating the subset. +*/ + extern int cidset; + boolean make_tt_subset(PDF pdf, fd_entry * fd, unsigned char *buff, int buflen) { @@ -270,48 +234,38 @@ boolean make_tt_subset(PDF pdf, fd_entry * fd, unsigned char *buff, int buflen) sfnt *sfont; pdf_obj *fontfile; int error = 0; - cidtogidmap = NULL; - sfont = sfnt_open(buff, buflen); - if (sfont->type == SFNT_TYPE_TTC) { i = ff_get_ttc_index(fd->fm->ff_name, fd->fm->ps_name); error = sfnt_read_table_directory(sfont, ttc_read_offset(sfont, (int) i, fd)); } else { error = sfnt_read_table_directory(sfont, 0); } - if (error < 0) { normal_error("type 2","parsing the TTF directory fails"); } - if (sfont->type == SFNT_TYPE_TTC && sfnt_find_table_pos(sfont, "CFF ")) { sfnt_close(sfont); - return false; + return false; } - if (is_subsetted(fd->fm)) { - /* rebuild the glyph tables and create a fresh cidmap */ + /*tex Rebuild the glyph tables and create a fresh cidmap :*/ glyphs = tt_build_init(); - last_cid = 0; - avl_t_init(&t, fd->gl_tree); for (found = (glw_entry *) avl_t_first(&t, fd->gl_tree); found != NULL; found = (glw_entry *) avl_t_next(&t)) { if (found->id > last_cid) last_cid = found->id; } - #ifndef NO_GHOSTSCRIPT_BUG cidtogidmap = NULL; #else cidtogidmap = xmalloc(((last_cid + 1) * 2) * sizeof(unsigned char)); memset(cidtogidmap, 0, (last_cid + 1) * 2); #endif - - /* fill |used_chars| */ + /*tex Fill |used_chars|: */ used_chars = xmalloc((last_cid + 1) * sizeof(char)); memset(used_chars, 0, (last_cid + 1)); avl_t_init(&t, fd->gl_tree); @@ -319,56 +273,44 @@ boolean make_tt_subset(PDF pdf, fd_entry * fd, unsigned char *buff, int buflen) found != NULL; found = (glw_entry *) avl_t_next(&t)) { used_chars[found->id] = 1; } - - /* Map CIDs to GIDs. */ - - num_glyphs = 1; /* \.{.notdef} */ + /*tex Map CIDs to GIDs, with |.notdef| in slot zero: */ + num_glyphs = 1; for (cid = 1; cid <= (long) last_cid; cid++) { if (used_chars[cid] == 0) continue; gid = (short unsigned) cid; - - #ifndef NO_GHOSTSCRIPT_BUG gid = tt_add_glyph(glyphs, (USHORT) gid, (USHORT) cid); #else gid = tt_add_glyph(glyphs, (USHORT) gid, (USHORT) num_glyphs); cidtogidmap[2 * cid] = gid >> 8; cidtogidmap[2 * cid + 1] = gid & 0xff; -#endif /* |!NO_GHOSTSCRIPT_BUG| */ - +#endif num_glyphs++; } if (num_glyphs == 1) { normal_error("type 2","there are no glyphs in the subset"); } - if (tt_build_tables(sfont, glyphs, fd) < 0) { normal_error("type 2","the TTF buffer can't be parsed"); } - tt_build_finish(glyphs); } - - /* Create font file */ - + /*tex Create the font file: */ for (i = 0; required_table[i].name; i++) { if (sfnt_require_table(sfont,required_table[i].name, required_table[i].must_exist) < 0) { normal_error("type 2","some required TrueType table does not exist"); } } - fontfile = sfnt_create_FontFile_stream(sfont); - - /* squeeze in the cidgidmap */ + /*tex The |cidgidmap|: */ if (cidtogidmap != NULL) { cidtogid_obj = (unsigned long) pdf_create_obj(pdf, obj_type_others, 0); pdf_begin_obj(pdf, (int) cidtogid_obj, OBJSTM_NEVER); pdf_begin_dict(pdf); pdf_dict_add_int(pdf, "Length", ((last_cid + 1) * 2)); pdf_end_dict(pdf); - assert(0); /* code unused */ pdf_begin_stream(pdf); pdf_room(pdf, (int) ((last_cid + 1) * 2)); for (i = 0; i < ((int) (last_cid + 1) * 2); i++) { @@ -377,15 +319,14 @@ boolean make_tt_subset(PDF pdf, fd_entry * fd, unsigned char *buff, int buflen) pdf_end_stream(pdf); pdf_end_obj(pdf); } - - /* the tff subset */ + /*tex The tff subset: */ for (i = 0; i < (int) (fontfile->length); i++) strbuf_putchar(pdf->fb, fontfile->data[i]); - pdf_release_obj(fontfile); - - /* CIDSet: a table of bits indexed by cid, bytes with high order bit first, - each (set) bit is a (present) CID. */ + /*tex + |CIDSet| is a table of bits indexed by cid, bytes with high order bit + first, each (set) bit is a (present) CID. + */ if (is_subsetted(fd->fm)) { if ((! pdf->omit_cidset) && (pdf->major_version == 1)) { cidset = pdf_create_obj(pdf, obj_type_others, 0); @@ -409,23 +350,6 @@ boolean make_tt_subset(PDF pdf, fd_entry * fd, unsigned char *buff, int buflen) } } } - - /* TODO other stuff that needs fixing: */ - - /* DW, W, DW2, and W2 */ -#if 0 - if (opt_flags & CIDFONT_FORCE_FIXEDPITCH) { - pdf_add_dict(font->fontdict, - pdf_new_name("DW"), pdf_new_number(1000.0)); - } else { - add_TTCIDHMetrics(font->fontdict, glyphs, used_chars, cidtogidmap, - last_cid); - if (v_used_chars) - add_TTCIDVMetrics(font->fontdict, glyphs, used_chars, cidtogidmap, - last_cid); - } -#endif - xfree(used_chars); sfnt_close(sfont); return true; |