summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/font/luafont.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/font/luafont.c')
-rw-r--r--Build/source/texk/web2c/luatexdir/font/luafont.c3445
1 files changed, 1933 insertions, 1512 deletions
diff --git a/Build/source/texk/web2c/luatexdir/font/luafont.c b/Build/source/texk/web2c/luatexdir/font/luafont.c
index 4a2eda1f41c..d9fd6273b06 100644
--- a/Build/source/texk/web2c/luatexdir/font/luafont.c
+++ b/Build/source/texk/web2c/luatexdir/font/luafont.c
@@ -1,316 +1,477 @@
+/* luafont.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 "luatex-api.h"
#include <ptexlib.h>
#include "nodes.h"
+static const char _svn_version[] =
+ "$Id: luafont.c 2086 2009-03-22 15:32:08Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/font/luafont.c $";
+
#define noVERBOSE
#define SAVE_REF 1
-char *font_type_strings[] = {"unknown","virtual","real", NULL};
-char *font_format_strings[] = {"unknown","type1","type3","truetype", "opentype", NULL};
-char *font_embedding_strings[] = {"unknown","no","subset", "full", NULL};
-char *ligature_type_strings[] = {"=:", "=:|", "|=:", "|=:|", "", "=:|>", "|=:>", "|=:|>", "", "", "", "|=:|>>", NULL };
+char *font_type_strings[] = { "unknown", "virtual", "real", NULL };
+char *font_format_strings[] =
+ { "unknown", "type1", "type3", "truetype", "opentype", NULL };
+char *font_embedding_strings[] = { "unknown", "no", "subset", "full", NULL };
+char *ligature_type_strings[] =
+ { "=:", "=:|", "|=:", "|=:|", "", "=:|>", "|=:>", "|=:|>", "", "", "",
+ "|=:|>>", NULL
+};
+
+const char *MATH_param_names[] = {
+ "nil",
+ "ScriptPercentScaleDown",
+ "ScriptScriptPercentScaleDown",
+ "DelimitedSubFormulaMinHeight",
+ "DisplayOperatorMinHeight",
+ "MathLeading",
+ "AxisHeight",
+ "AccentBaseHeight",
+ "FlattenedAccentBaseHeight",
+ "SubscriptShiftDown",
+ "SubscriptTopMax",
+ "SubscriptBaselineDropMin",
+ "SuperscriptShiftUp",
+ "SuperscriptShiftUpCramped",
+ "SuperscriptBottomMin",
+ "SuperscriptBaselineDropMax",
+ "SubSuperscriptGapMin",
+ "SuperscriptBottomMaxWithSubscript",
+ "SpaceAfterScript",
+ "UpperLimitGapMin",
+ "UpperLimitBaselineRiseMin",
+ "LowerLimitGapMin",
+ "LowerLimitBaselineDropMin",
+ "StackTopShiftUp",
+ "StackTopDisplayStyleShiftUp",
+ "StackBottomShiftDown",
+ "StackBottomDisplayStyleShiftDown",
+ "StackGapMin",
+ "StackDisplayStyleGapMin",
+ "StretchStackTopShiftUp",
+ "StretchStackBottomShiftDown",
+ "StretchStackGapAboveMin",
+ "StretchStackGapBelowMin",
+ "FractionNumeratorShiftUp",
+ "FractionNumeratorDisplayStyleShiftUp",
+ "FractionDenominatorShiftDown",
+ "FractionDenominatorDisplayStyleShiftDown",
+ "FractionNumeratorGapMin",
+ "FractionNumeratorDisplayStyleGapMin",
+ "FractionRuleThickness",
+ "FractionDenominatorGapMin",
+ "FractionDenominatorDisplayStyleGapMin",
+ "SkewedFractionHorizontalGap",
+ "SkewedFractionVerticalGap",
+ "OverbarVerticalGap",
+ "OverbarRuleThickness",
+ "OverbarExtraAscender",
+ "UnderbarVerticalGap",
+ "UnderbarRuleThickness",
+ "UnderbarExtraDescender",
+ "RadicalVerticalGap",
+ "RadicalDisplayStyleVerticalGap",
+ "RadicalRuleThickness",
+ "RadicalExtraAscender",
+ "RadicalKernBeforeDegree",
+ "RadicalKernAfterDegree",
+ "RadicalDegreeBottomRaisePercent",
+ "MinConnectorOverlap",
+ NULL,
+};
+
+static void dump_intfield(lua_State * L, char *n, int c)
+{
+ lua_pushstring(L, n);
+ lua_pushnumber(L, c);
+ lua_rawset(L, -3);
+}
-void
-font_char_to_lua (lua_State *L, internalfontnumber f, charinfo *co) {
- int i;
- liginfo *l;
- kerninfo *ki;
-
- lua_createtable(L,0,10);
-
- lua_pushstring(L,"width");
- lua_pushnumber(L,get_charinfo_width(co));
- lua_rawset(L,-3);
-
- lua_pushstring(L,"height");
- lua_pushnumber(L,get_charinfo_height(co));
- lua_rawset(L,-3);
-
- lua_pushstring(L,"depth");
- lua_pushnumber(L,get_charinfo_depth(co));
- lua_rawset(L,-3);
-
- lua_pushstring(L,"italic");
- lua_pushnumber(L,get_charinfo_italic(co));
- lua_rawset(L,-3);
-
- if (get_charinfo_ef(co)!=0) {
- lua_pushstring(L,"expansion_factor");
- lua_pushnumber(L,get_charinfo_ef(co));
- lua_rawset(L,-3);
- }
-
- if (get_charinfo_lp(co)!=0) {
- lua_pushstring(L,"left_protruding");
- lua_pushnumber(L,get_charinfo_lp(co));
- lua_rawset(L,-3);
- }
-
- if (get_charinfo_lp(co)!=0) {
- lua_pushstring(L,"right_protruding");
- lua_pushnumber(L,get_charinfo_rp(co));
- lua_rawset(L,-3);
- }
-
-
- if (font_encodingbytes(f) == 2 ) {
- lua_pushstring(L,"index");
- lua_pushnumber(L,get_charinfo_index(co));
- lua_rawset(L,-3);
- }
-
- if (get_charinfo_name(co)!=NULL) {
- lua_pushstring(L,"name");
- lua_pushstring(L,get_charinfo_name(co));
- lua_rawset(L,-3);
- }
-
- if (get_charinfo_tounicode(co)!=NULL) {
- lua_pushstring(L,"tounicode");
- lua_pushstring(L,get_charinfo_tounicode(co));
- lua_rawset(L,-3);
- }
-
- if (get_charinfo_tag(co) == list_tag) {
- lua_pushstring(L,"next");
- lua_pushnumber(L,get_charinfo_remainder(co));
- lua_rawset(L,-3);
- }
-
- lua_pushstring(L,"used");
- lua_pushboolean(L,(get_charinfo_used(co) ? true : false));
- lua_rawset(L,-3);
-
- if (get_charinfo_tag(co) == ext_tag) {
- lua_pushstring(L,"extensible");
- lua_createtable(L,0,4);
- lua_pushnumber(L,get_charinfo_extensible(co,EXT_TOP));
- lua_setfield(L,-2,"top");
- lua_pushnumber(L,get_charinfo_extensible(co,EXT_BOT));
- lua_setfield(L,-2,"bot");
- lua_pushnumber(L,get_charinfo_extensible(co,EXT_MID));
- lua_setfield(L,-2,"mid");
- lua_pushnumber(L,get_charinfo_extensible(co,EXT_REP));
- lua_setfield(L,-2,"rep");
- lua_rawset(L,-3);
- }
- ki = get_charinfo_kerns(co);
- if (ki != NULL) {
- lua_pushstring(L,"kerns");
- lua_createtable(L,10,1);
- for (i=0;!kern_end(ki[i]);i++) {
- if (kern_char(ki[i]) == right_boundarychar) {
- lua_pushstring(L,"right_boundary");
- } else {
- lua_pushnumber(L,kern_char(ki[i]));
- }
- lua_pushnumber(L,kern_kern(ki[i]));
- lua_rawset(L,-3);
- }
- lua_rawset(L,-3);
- }
- l = get_charinfo_ligatures(co);
- if (l!=NULL) {
- lua_pushstring(L,"ligatures");
- lua_createtable(L,10,1);
- for (i=0;!lig_end(l[i]);i++) {
- if (lig_char(l[i]) == right_boundarychar) {
- lua_pushstring(L,"right_boundary");
- } else {
- lua_pushnumber(L,lig_char(l[i]));
- }
- lua_createtable(L,0,2);
- lua_pushstring(L,"type");
- lua_pushnumber(L,lig_type(l[i]));
- lua_rawset(L,-3);
- lua_pushstring(L,"char");
- lua_pushnumber(L,lig_replacement(l[i]));
- lua_rawset(L,-3);
- lua_rawset(L,-3);
- }
- lua_rawset(L,-3);
- }
+
+
+void font_char_to_lua(lua_State * L, internalfontnumber f, charinfo * co)
+{
+ int i;
+ liginfo *l;
+ kerninfo *ki;
+
+ lua_createtable(L, 0, 10);
+
+ lua_pushstring(L, "width");
+ lua_pushnumber(L, get_charinfo_width(co));
+ lua_rawset(L, -3);
+
+ lua_pushstring(L, "height");
+ lua_pushnumber(L, get_charinfo_height(co));
+ lua_rawset(L, -3);
+
+ lua_pushstring(L, "depth");
+ lua_pushnumber(L, get_charinfo_depth(co));
+ lua_rawset(L, -3);
+
+ lua_pushstring(L, "italic");
+ lua_pushnumber(L, get_charinfo_italic(co));
+ lua_rawset(L, -3);
+
+ lua_pushstring(L, "top_accent");
+ lua_pushnumber(L, get_charinfo_top_accent(co));
+ lua_rawset(L, -3);
+
+ lua_pushstring(L, "bot_accent");
+ lua_pushnumber(L, get_charinfo_bot_accent(co));
+ lua_rawset(L, -3);
+
+
+ if (get_charinfo_ef(co) != 0) {
+ lua_pushstring(L, "expansion_factor");
+ lua_pushnumber(L, get_charinfo_ef(co));
+ lua_rawset(L, -3);
+ }
+
+ if (get_charinfo_lp(co) != 0) {
+ lua_pushstring(L, "left_protruding");
+ lua_pushnumber(L, get_charinfo_lp(co));
+ lua_rawset(L, -3);
+ }
+
+ if (get_charinfo_lp(co) != 0) {
+ lua_pushstring(L, "right_protruding");
+ lua_pushnumber(L, get_charinfo_rp(co));
+ lua_rawset(L, -3);
+ }
+
+
+ if (font_encodingbytes(f) == 2) {
+ lua_pushstring(L, "index");
+ lua_pushnumber(L, get_charinfo_index(co));
+ lua_rawset(L, -3);
+ }
+
+ if (get_charinfo_name(co) != NULL) {
+ lua_pushstring(L, "name");
+ lua_pushstring(L, get_charinfo_name(co));
+ lua_rawset(L, -3);
+ }
+
+ if (get_charinfo_tounicode(co) != NULL) {
+ lua_pushstring(L, "tounicode");
+ lua_pushstring(L, get_charinfo_tounicode(co));
+ lua_rawset(L, -3);
+ }
+
+ if (get_charinfo_tag(co) == list_tag) {
+ lua_pushstring(L, "next");
+ lua_pushnumber(L, get_charinfo_remainder(co));
+ lua_rawset(L, -3);
+ }
+
+ lua_pushstring(L, "used");
+ lua_pushboolean(L, (get_charinfo_used(co) ? true : false));
+ lua_rawset(L, -3);
+
+ if (get_charinfo_tag(co) == ext_tag) {
+ extinfo *h;
+ h = get_charinfo_hor_variants(co);
+ if (h != NULL) {
+ int i = 1;
+ lua_newtable(L);
+ while (h != NULL) {
+ lua_createtable(L, 0, 5);
+ dump_intfield(L, "glyph", h->glyph);
+ dump_intfield(L, "extender", h->extender);
+ dump_intfield(L, "start", h->start_overlap);
+ dump_intfield(L, "end", h->end_overlap);
+ dump_intfield(L, "advance", h->advance);
+ lua_rawseti(L, -2, i);
+ i++;
+ h = h->next;
+ }
+ lua_setfield(L, -2, "horiz_variants");
+ }
+ h = get_charinfo_vert_variants(co);
+ if (h != NULL) {
+ int i = 1;
+ lua_newtable(L);
+ while (h != NULL) {
+ lua_createtable(L, 0, 5);
+ dump_intfield(L, "glyph", h->glyph);
+ dump_intfield(L, "extender", h->extender);
+ dump_intfield(L, "start", h->start_overlap);
+ dump_intfield(L, "end", h->end_overlap);
+ dump_intfield(L, "advance", h->advance);
+ lua_rawseti(L, -2, i);
+ i++;
+ h = h->next;
+ }
+ lua_setfield(L, -2, "vert_variants");
+ }
+ }
+ ki = get_charinfo_kerns(co);
+ if (ki != NULL) {
+ lua_pushstring(L, "kerns");
+ lua_createtable(L, 10, 1);
+ for (i = 0; !kern_end(ki[i]); i++) {
+ if (kern_char(ki[i]) == right_boundarychar) {
+ lua_pushstring(L, "right_boundary");
+ } else {
+ lua_pushnumber(L, kern_char(ki[i]));
+ }
+ lua_pushnumber(L, kern_kern(ki[i]));
+ lua_rawset(L, -3);
+ }
+ lua_rawset(L, -3);
+ }
+ l = get_charinfo_ligatures(co);
+ if (l != NULL) {
+ lua_pushstring(L, "ligatures");
+ lua_createtable(L, 10, 1);
+ for (i = 0; !lig_end(l[i]); i++) {
+ if (lig_char(l[i]) == right_boundarychar) {
+ lua_pushstring(L, "right_boundary");
+ } else {
+ lua_pushnumber(L, lig_char(l[i]));
+ }
+ lua_createtable(L, 0, 2);
+ lua_pushstring(L, "type");
+ lua_pushnumber(L, lig_type(l[i]));
+ lua_rawset(L, -3);
+ lua_pushstring(L, "char");
+ lua_pushnumber(L, lig_replacement(l[i]));
+ lua_rawset(L, -3);
+ lua_rawset(L, -3);
+ }
+ lua_rawset(L, -3);
+ }
}
-static void
-write_lua_parameters (lua_State *L, int f) {
- int k;
- lua_newtable(L);
- for (k=1;k<=font_params(f);k++) {
- lua_pushnumber(L,font_param(f,k));
- switch (k) {
- case slant_code: lua_setfield(L,-2,"slant"); break;
- case space_code: lua_setfield(L,-2,"space"); break;
- case space_stretch_code: lua_setfield(L,-2,"space_stretch"); break;
- case space_shrink_code: lua_setfield(L,-2,"space_shrink"); break;
- case x_height_code: lua_setfield(L,-2,"x_height"); break;
- case quad_code: lua_setfield(L,-2,"quad"); break;
- case extra_space_code: lua_setfield(L,-2,"extra_space"); break;
- default:
- lua_rawseti(L,-2,k);
- }
- }
- lua_setfield(L,-2,"parameters");
+static void write_lua_parameters(lua_State * L, int f)
+{
+ int k;
+ lua_newtable(L);
+ for (k = 1; k <= font_params(f); k++) {
+ lua_pushnumber(L, font_param(f, k));
+ switch (k) {
+ case slant_code:
+ lua_setfield(L, -2, "slant");
+ break;
+ case space_code:
+ lua_setfield(L, -2, "space");
+ break;
+ case space_stretch_code:
+ lua_setfield(L, -2, "space_stretch");
+ break;
+ case space_shrink_code:
+ lua_setfield(L, -2, "space_shrink");
+ break;
+ case x_height_code:
+ lua_setfield(L, -2, "x_height");
+ break;
+ case quad_code:
+ lua_setfield(L, -2, "quad");
+ break;
+ case extra_space_code:
+ lua_setfield(L, -2, "extra_space");
+ break;
+ default:
+ lua_rawseti(L, -2, k);
+ }
+ }
+ lua_setfield(L, -2, "parameters");
}
-int
-font_to_lua (lua_State *L, int f) {
- int k;
- charinfo *co;
- if (font_cache_id(f)) {
- /* 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 */
- write_lua_parameters(L,f);
+static void write_lua_math_parameters(lua_State * L, int f)
+{
+ int k;
+ lua_newtable(L);
+ for (k = 1; k < font_math_params(f); k++) {
+ lua_pushnumber(L, font_math_param(f, k));
+ if (k <= MATH_param_max) {
+ lua_setfield(L, -2, MATH_param_names[k]);
+ } else {
+ lua_rawseti(L, -2, k);
+ }
+ }
+ lua_setfield(L, -2, "MathConstants");
+}
+
+
+
+int font_to_lua(lua_State * L, int f)
+{
+ int k;
+ charinfo *co;
+ if (font_cache_id(f)) {
+ /* 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 */
+ write_lua_parameters(L, f);
+ return 1;
+ }
+
+ lua_newtable(L);
+ lua_pushstring(L, font_name(f));
+ lua_setfield(L, -2, "name");
+ if (font_area(f) != NULL) {
+ lua_pushstring(L, font_area(f));
+ lua_setfield(L, -2, "area");
+ }
+ if (font_filename(f) != NULL) {
+ lua_pushstring(L, font_filename(f));
+ lua_setfield(L, -2, "filename");
+ }
+ if (font_fullname(f) != NULL) {
+ lua_pushstring(L, font_fullname(f));
+ lua_setfield(L, -2, "fullname");
+ }
+ if (font_encodingname(f) != NULL) {
+ lua_pushstring(L, font_encodingname(f));
+ lua_setfield(L, -2, "encodingname");
+ }
+
+ lua_pushboolean(L, (font_used(f) ? true : false));
+ lua_setfield(L, -2, "used");
+
+
+ lua_pushstring(L, font_type_strings[font_type(f)]);
+ lua_setfield(L, -2, "type");
+ lua_pushstring(L, font_format_strings[font_format(f)]);
+ lua_setfield(L, -2, "format");
+ lua_pushstring(L, font_embedding_strings[font_embedding(f)]);
+ lua_setfield(L, -2, "embedding");
+
+ lua_pushnumber(L, font_size(f));
+ lua_setfield(L, -2, "size");
+ lua_pushnumber(L, font_dsize(f));
+ lua_setfield(L, -2, "designsize");
+ lua_pushnumber(L, font_checksum(f));
+ lua_setfield(L, -2, "checksum");
+ lua_pushnumber(L, font_slant(f));
+ lua_setfield(L, -2, "slant");
+ lua_pushnumber(L, font_extend(f));
+ lua_setfield(L, -2, "extend");
+ lua_pushnumber(L, font_natural_dir(f));
+ lua_setfield(L, -2, "direction");
+ lua_pushnumber(L, font_encodingbytes(f));
+ lua_setfield(L, -2, "encodingbytes");
+ lua_pushnumber(L, font_tounicode(f));
+ lua_setfield(L, -2, "tounicode");
+
+ /* pdf parameters */
+ /* skip the first four for now, that are very much interal */
+ /*
+ if (pdf_font_size(f) != 0) {
+ lua_pushnumber(L,pdf_font_size(f));
+ lua_setfield(L,-2,"pdf_size");
+ }
+ if (pdf_font_num(f) != 0) {
+ lua_pushnumber(L,pdf_font_num(f));
+ lua_setfield(L,-2,"pdf_num");
+ }
+ if (pdf_font_blink(f) != 0) {
+ lua_pushnumber(L,pdf_font_blink(f));
+ lua_setfield(L,-2,"pdf_blink");
+ }
+ if (pdf_font_elink(f) != 0) {
+ lua_pushnumber(L,pdf_font_elink(f));
+ lua_setfield(L,-2,"pdf_elink");
+ }
+ */
+ /* the next one is read only */
+ if (pdf_font_expand_ratio(f) != 0) {
+ lua_pushnumber(L, pdf_font_expand_ratio(f));
+ lua_setfield(L, -2, "expand_ratio");
+ }
+ if (pdf_font_shrink(f) != 0) {
+ lua_pushnumber(L, pdf_font_shrink(f));
+ lua_setfield(L, -2, "shrink");
+ }
+ if (pdf_font_stretch(f) != 0) {
+ lua_pushnumber(L, pdf_font_stretch(f));
+ lua_setfield(L, -2, "stretch");
+ }
+ if (pdf_font_step(f) != 0) {
+ lua_pushnumber(L, pdf_font_step(f));
+ lua_setfield(L, -2, "step");
+ }
+ if (pdf_font_auto_expand(f) != 0) {
+ lua_pushboolean(L, pdf_font_auto_expand(f));
+ lua_setfield(L, -2, "auto_expand");
+ }
+ if (pdf_font_attr(f) != 0) {
+ lua_pushstring(L, makecstring(pdf_font_attr(f)));
+ lua_setfield(L, -2, "attributes");
+ }
+
+ /* params */
+ write_lua_parameters(L, f);
+ write_lua_math_parameters(L, f);
+
+ /* chars */
+ lua_createtable(L, font_tables[f]->charinfo_size, 0); /* all characters */
+
+ if (has_left_boundary(f)) {
+ co = get_charinfo(f, left_boundarychar);
+ font_char_to_lua(L, f, co);
+ lua_setfield(L, -2, "left_boundary");
+ }
+ if (has_right_boundary(f)) {
+ co = get_charinfo(f, right_boundarychar);
+ font_char_to_lua(L, f, co);
+ lua_setfield(L, -2, "right_boundary");
+ }
+
+ for (k = font_bc(f); k <= font_ec(f); k++) {
+ if (char_exists(f, k)) {
+ lua_pushnumber(L, k);
+ co = get_charinfo(f, k);
+ font_char_to_lua(L, f, co);
+ lua_rawset(L, -3);
+ }
+ }
+ lua_setfield(L, -2, "characters");
return 1;
- }
-
- lua_newtable(L);
- lua_pushstring(L,font_name(f));
- lua_setfield(L,-2,"name");
- if(font_area(f)!=NULL) {
- lua_pushstring(L,font_area(f));
- lua_setfield(L,-2,"area");
- }
- if(font_filename(f)!=NULL) {
- lua_pushstring(L,font_filename(f));
- lua_setfield(L,-2,"filename");
- }
- if(font_fullname(f)!=NULL) {
- lua_pushstring(L,font_fullname(f));
- lua_setfield(L,-2,"fullname");
- }
- if(font_encodingname(f)!=NULL) {
- lua_pushstring(L,font_encodingname(f));
- lua_setfield(L,-2,"encodingname");
- }
-
- lua_pushboolean(L,(font_used(f) ? true : false));
- lua_setfield(L,-2,"used");
-
-
- lua_pushstring(L,font_type_strings[font_type(f)]);
- lua_setfield(L,-2,"type");
- lua_pushstring(L,font_format_strings[font_format(f)]);
- lua_setfield(L,-2,"format");
- lua_pushstring(L,font_embedding_strings[font_embedding(f)]);
- lua_setfield(L,-2,"embedding");
-
- lua_pushnumber(L,font_size(f));
- lua_setfield(L,-2,"size");
- lua_pushnumber(L,font_dsize(f));
- lua_setfield(L,-2,"designsize");
- lua_pushnumber(L,font_checksum(f));
- lua_setfield(L,-2,"checksum");
- lua_pushnumber(L,font_slant(f));
- lua_setfield(L,-2,"slant");
- lua_pushnumber(L,font_extend(f));
- lua_setfield(L,-2,"extend");
- lua_pushnumber(L,font_natural_dir(f));
- lua_setfield(L,-2,"direction");
- lua_pushnumber(L,font_encodingbytes(f));
- lua_setfield(L,-2,"encodingbytes");
- lua_pushnumber(L,font_tounicode(f));
- lua_setfield(L,-2,"tounicode");
-
- /* pdf parameters */
- /* skip the first four for now, that are very much interal */
- /*
- if (pdf_font_size(f) != 0) {
- lua_pushnumber(L,pdf_font_size(f));
- lua_setfield(L,-2,"pdf_size");
- }
- if (pdf_font_num(f) != 0) {
- lua_pushnumber(L,pdf_font_num(f));
- lua_setfield(L,-2,"pdf_num");
- }
- if (pdf_font_blink(f) != 0) {
- lua_pushnumber(L,pdf_font_blink(f));
- lua_setfield(L,-2,"pdf_blink");
- }
- if (pdf_font_elink(f) != 0) {
- lua_pushnumber(L,pdf_font_elink(f));
- lua_setfield(L,-2,"pdf_elink");
- }
- */
- /* the next one is read only */
- if (pdf_font_expand_ratio(f) != 0) {
- lua_pushnumber(L,pdf_font_expand_ratio(f));
- lua_setfield(L,-2,"expand_ratio");
- }
- if (pdf_font_shrink(f) != 0) {
- lua_pushnumber(L,pdf_font_shrink(f));
- lua_setfield(L,-2,"shrink");
- }
- if (pdf_font_stretch(f) != 0) {
- lua_pushnumber(L,pdf_font_stretch(f));
- lua_setfield(L,-2,"stretch");
- }
- if (pdf_font_step(f) != 0) {
- lua_pushnumber(L,pdf_font_step(f));
- lua_setfield(L,-2,"step");
- }
- if (pdf_font_auto_expand(f) != 0) {
- lua_pushboolean(L,pdf_font_auto_expand(f));
- lua_setfield(L,-2,"auto_expand");
- }
- if (pdf_font_attr(f) != 0) {
- lua_pushstring(L,makecstring(pdf_font_attr(f)));
- lua_setfield(L,-2,"attributes");
- }
-
- /* params */
- write_lua_parameters(L,f);
-
- /* chars */
- lua_createtable(L,font_tables[f]->charinfo_size,0); /* all characters */
-
- if (has_left_boundary(f)) {
- co = get_charinfo(f,left_boundarychar);
- font_char_to_lua(L,f,co);
- lua_setfield(L,-2,"left_boundary");
- }
- if (has_right_boundary(f)) {
- co = get_charinfo(f,right_boundarychar);
- font_char_to_lua(L,f,co);
- lua_setfield(L,-2,"right_boundary");
- }
-
- for (k=font_bc(f);k<=font_ec(f);k++) {
- if (char_exists(f,k)) {
- lua_pushnumber(L,k);
- co = get_charinfo(f,k);
- font_char_to_lua(L,f,co);
- lua_rawset(L,-3);
- }
- }
- lua_setfield(L,-2,"characters");
- return 1;
}
-static int
-count_hash_items (lua_State *L, int name_index){
- int n = -1;
- lua_rawgeti(L,LUA_REGISTRYINDEX,name_index);
- lua_rawget(L,-2);
- if (!lua_isnil(L,-1)) {
- if (lua_istable(L,-1)) {
- n = 0;
- /* now find the number */
- lua_pushnil(L); /* first key */
- while (lua_next(L, -2) != 0) {
- n++;
- lua_pop(L,1);
- }
- }
- }
- lua_pop(L,1);
- return n;
+static int count_hash_items(lua_State * L, int name_index)
+{
+ int n = -1;
+ lua_rawgeti(L, LUA_REGISTRYINDEX, name_index);
+ lua_rawget(L, -2);
+ if (!lua_isnil(L, -1)) {
+ if (lua_istable(L, -1)) {
+ n = 0;
+ /* now find the number */
+ lua_pushnil(L); /* first key */
+ while (lua_next(L, -2) != 0) {
+ n++;
+ lua_pop(L, 1);
+ }
+ }
+ }
+ lua_pop(L, 1);
+ return n;
}
#define streq(a,b) (strcmp(a,b)==0)
@@ -321,130 +482,130 @@ count_hash_items (lua_State *L, int name_index){
append_packet((l&0xFF000000)>>24); \
append_packet((l&0x00FF0000)>>16); \
append_packet((l&0x0000FF00)>>8); \
- append_packet((l&0x000000FF)); }
+ append_packet((l&0x000000FF)); }
/*
*/
#define lua_roundnumber(a,b) (int)floor((double)lua_tonumber(L,-1)+0.5)
-static int
-numeric_field (lua_State *L, char *name, int dflt) {
- int i = dflt;
- lua_pushstring(L,name);
- lua_rawget(L,-2);
- if (lua_isnumber(L,-1)) {
- i = lua_roundnumber(L,-1);
- }
- lua_pop(L,1);
- return i;
+static int numeric_field(lua_State * L, char *name, int dflt)
+{
+ int i = dflt;
+ lua_pushstring(L, name);
+ lua_rawget(L, -2);
+ if (lua_isnumber(L, -1)) {
+ i = lua_roundnumber(L, -1);
+ }
+ lua_pop(L, 1);
+ return i;
}
-static int
-n_numeric_field (lua_State *L, int name_index, int dflt) {
- register int i = dflt;
- lua_rawgeti(L,LUA_REGISTRYINDEX, name_index); /* fetch the stringptr */
- lua_rawget(L,-2);
- if (lua_type(L,-1)==LUA_TNUMBER) {
- i = lua_roundnumber(L,-1);
- }
- lua_pop(L,1);
- return i;
+static int n_numeric_field(lua_State * L, int name_index, int dflt)
+{
+ register int i = dflt;
+ lua_rawgeti(L, LUA_REGISTRYINDEX, name_index); /* fetch the stringptr */
+ lua_rawget(L, -2);
+ if (lua_type(L, -1) == LUA_TNUMBER) {
+ i = lua_roundnumber(L, -1);
+ }
+ lua_pop(L, 1);
+ return i;
}
-static int
-enum_field (lua_State *L, char *name, int dflt, char **values) {
- int k;
- char *s;
- int i = dflt;
- lua_pushstring(L,name);
- lua_rawget(L,-2);
- if (lua_isnumber(L,-1)) {
- i = lua_tonumber(L,-1);
- } else if (lua_isstring(L,-1)) {
- s = (char *)lua_tostring(L,-1);
- k = 0;
- while (values[k] != NULL) {
- if (strcmp(values[k],s) == 0) {
- i = k;
- break;
- }
- k++;
- }
- }
- lua_pop(L,1);
- return i;
+static int enum_field(lua_State * L, char *name, int dflt, char **values)
+{
+ int k;
+ char *s;
+ int i = dflt;
+ lua_pushstring(L, name);
+ lua_rawget(L, -2);
+ if (lua_isnumber(L, -1)) {
+ i = lua_tonumber(L, -1);
+ } else if (lua_isstring(L, -1)) {
+ s = (char *) lua_tostring(L, -1);
+ k = 0;
+ while (values[k] != NULL) {
+ if (strcmp(values[k], s) == 0) {
+ i = k;
+ break;
+ }
+ k++;
+ }
+ }
+ lua_pop(L, 1);
+ return i;
}
-static int
-boolean_field (lua_State *L, char *name, int dflt) {
- int i = dflt;
- lua_pushstring(L,name);
- lua_rawget(L,-2);
- if (lua_isboolean(L,-1)) {
- i = lua_toboolean(L,-1);
- }
- lua_pop(L,1);
- return i;
+static int boolean_field(lua_State * L, char *name, int dflt)
+{
+ int i = dflt;
+ lua_pushstring(L, name);
+ lua_rawget(L, -2);
+ if (lua_isboolean(L, -1)) {
+ i = lua_toboolean(L, -1);
+ }
+ lua_pop(L, 1);
+ return i;
}
-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 */
- lua_rawget(L,-2);
- if (lua_isboolean(L,-1)) {
- i = lua_toboolean(L,-1);
- }
- lua_pop(L,1);
- return i;
+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 */
+ lua_rawget(L, -2);
+ if (lua_isboolean(L, -1)) {
+ i = lua_toboolean(L, -1);
+ }
+ lua_pop(L, 1);
+ return i;
}
-static char *
-string_field (lua_State *L, char *name, char *dflt) {
- char *i;
- lua_pushstring(L,name);
- lua_rawget(L,-2);
- if (lua_isstring(L,-1)) {
- i = xstrdup(lua_tostring(L,-1));
- } else if (dflt==NULL) {
- i = NULL;
- } else {
- i = xstrdup(dflt);
- }
- lua_pop(L,1);
- return i;
+static char *string_field(lua_State * L, char *name, char *dflt)
+{
+ char *i;
+ lua_pushstring(L, name);
+ lua_rawget(L, -2);
+ if (lua_isstring(L, -1)) {
+ i = xstrdup(lua_tostring(L, -1));
+ } else if (dflt == NULL) {
+ i = NULL;
+ } else {
+ i = xstrdup(dflt);
+ }
+ lua_pop(L, 1);
+ return i;
}
-static char *
-n_string_field (lua_State *L, int name_index, char *dflt) {
- char *i;
- lua_rawgeti(L,LUA_REGISTRYINDEX, name_index); /* fetch the stringptr */
- lua_rawget(L,-2);
- if (lua_isstring(L,-1)) {
- i = xstrdup(lua_tostring(L,-1));
- } else if (dflt==NULL) {
- i = NULL;
- } else {
- i = xstrdup(dflt);
- }
- lua_pop(L,1);
- return i;
+static char *n_string_field(lua_State * L, int name_index, char *dflt)
+{
+ char *i;
+ lua_rawgeti(L, LUA_REGISTRYINDEX, name_index); /* fetch the stringptr */
+ lua_rawget(L, -2);
+ if (lua_isstring(L, -1)) {
+ i = xstrdup(lua_tostring(L, -1));
+ } else if (dflt == NULL) {
+ i = NULL;
+ } else {
+ i = xstrdup(dflt);
+ }
+ lua_pop(L, 1);
+ return i;
}
-#define init_luaS_index(a) do { \
- lua_pushliteral(L,#a); \
- luaS_##a##_ptr = (char *)lua_tostring(L,-1); \
- luaS_##a##_index = luaL_ref (L,LUA_REGISTRYINDEX); \
+#define init_luaS_index(a) do { \
+ lua_pushliteral(L,#a); \
+ luaS_##a##_ptr = (char *)lua_tostring(L,-1); \
+ luaS_##a##_index = luaL_ref (L,LUA_REGISTRYINDEX); \
} while (0)
-#define make_luaS_index(a) \
- static int luaS_##a##_index = 0; \
+#define make_luaS_index(a) \
+ static int luaS_##a##_index = 0; \
static char * luaS_##a##_ptr = NULL
-#define luaS_index(a) luaS_##a##_index
+#define luaS_index(a) luaS_##a##_index
#define luaS_ptr_eq(a,b) (a==luaS_##b##_ptr)
@@ -452,13 +613,15 @@ make_luaS_index(width);
make_luaS_index(height);
make_luaS_index(depth);
make_luaS_index(italic);
+make_luaS_index(top_accent);
+make_luaS_index(bot_accent);
make_luaS_index(index);
make_luaS_index(left_protruding);
make_luaS_index(right_protruding);
make_luaS_index(expansion_factor);
-make_luaS_index(top);
-make_luaS_index(bot);
-make_luaS_index(rep);
+make_luaS_index(top);
+make_luaS_index(bot);
+make_luaS_index(rep);
make_luaS_index(mid);
make_luaS_index(next);
make_luaS_index(used);
@@ -475,6 +638,7 @@ make_luaS_index(right);
make_luaS_index(node);
make_luaS_index(down);
make_luaS_index(special);
+make_luaS_index(image);
make_luaS_index(slant);
make_luaS_index(space);
make_luaS_index(space_stretch);
@@ -487,455 +651,634 @@ make_luaS_index(right_boundary);
make_luaS_index(kerns);
make_luaS_index(ligatures);
make_luaS_index(fonts);
-
-void init_font_string_pointers (lua_State *L) {
- init_luaS_index(width);
- init_luaS_index(height);
- init_luaS_index(depth);
- init_luaS_index(italic);
- init_luaS_index(index);
- init_luaS_index(left_protruding);
- init_luaS_index(right_protruding);
- init_luaS_index(expansion_factor);
- init_luaS_index(top);
- init_luaS_index(bot);
- init_luaS_index(rep);
- init_luaS_index(mid);
- init_luaS_index(next);
- init_luaS_index(used);
- init_luaS_index(name);
- init_luaS_index(tounicode);
- init_luaS_index(font);
- init_luaS_index(char);
- init_luaS_index(slot);
- init_luaS_index(comment);
- init_luaS_index(push);
- init_luaS_index(pop);
- init_luaS_index(rule);
- init_luaS_index(right);
- init_luaS_index(node);
- init_luaS_index(down);
- init_luaS_index(special);
-
- init_luaS_index(slant);
- init_luaS_index(space);
- init_luaS_index(space_stretch);
- init_luaS_index(space_shrink);
- init_luaS_index(x_height);
- init_luaS_index(quad);
- init_luaS_index(extra_space);
-
- init_luaS_index(left_boundary);
- init_luaS_index(right_boundary);
- init_luaS_index(kerns);
- init_luaS_index(ligatures);
- init_luaS_index(fonts);
+make_luaS_index(extender);
+make_luaS_index(start);
+make_luaS_index(end);
+make_luaS_index(advance);
+make_luaS_index(glyph);
+
+void init_font_string_pointers(lua_State * L)
+{
+ init_luaS_index(width);
+ init_luaS_index(height);
+ init_luaS_index(depth);
+ init_luaS_index(italic);
+ init_luaS_index(top_accent);
+ init_luaS_index(bot_accent);
+ init_luaS_index(index);
+ init_luaS_index(left_protruding);
+ init_luaS_index(right_protruding);
+ init_luaS_index(expansion_factor);
+ init_luaS_index(top);
+ init_luaS_index(bot);
+ init_luaS_index(rep);
+ init_luaS_index(mid);
+ init_luaS_index(next);
+ init_luaS_index(used);
+ init_luaS_index(name);
+ init_luaS_index(tounicode);
+ init_luaS_index(font);
+ init_luaS_index(char);
+ init_luaS_index(slot);
+ init_luaS_index(comment);
+ init_luaS_index(push);
+ init_luaS_index(pop);
+ init_luaS_index(rule);
+ init_luaS_index(right);
+ init_luaS_index(node);
+ init_luaS_index(down);
+ init_luaS_index(special);
+ init_luaS_index(image);
+
+ init_luaS_index(slant);
+ init_luaS_index(space);
+ init_luaS_index(space_stretch);
+ init_luaS_index(space_shrink);
+ init_luaS_index(x_height);
+ init_luaS_index(quad);
+ init_luaS_index(extra_space);
+
+ init_luaS_index(left_boundary);
+ init_luaS_index(right_boundary);
+ init_luaS_index(kerns);
+ init_luaS_index(ligatures);
+ init_luaS_index(fonts);
+
+ init_luaS_index(extender);
+ init_luaS_index(start);
+ init_luaS_index(end);
+ init_luaS_index(advance);
+ init_luaS_index(glyph);
}
-static int
-count_char_packet_bytes (lua_State *L) {
- register int i;
- register int l = 0;
- int ff = 0;
- for (i=1;i<=lua_objlen(L,-1);i++) {
- lua_rawgeti(L,-1,i);
- if (lua_istable(L,-1)) {
- lua_rawgeti(L,-1,1);
- if (lua_isstring(L,-1)) {
- char *s = (char *)lua_tostring(L,-1);
- if (luaS_ptr_eq(s,font)) { l+= 5; ff =1; }
- else if (luaS_ptr_eq(s,char)) { if (ff==0) { l+=5; } l += 5; ff = 1; }
- else if (luaS_ptr_eq(s,slot)) { l += 10; ff = 1;}
- else if (luaS_ptr_eq(s,comment)) { ; }
- else if (luaS_ptr_eq(s,push) ||
- luaS_ptr_eq(s,pop)) { l++; }
- else if (luaS_ptr_eq(s,rule)) { l+=9; }
- else if (luaS_ptr_eq(s,right) ||
- luaS_ptr_eq(s,node) ||
- luaS_ptr_eq(s,down)) { l+=5; }
- else if (luaS_ptr_eq(s,special)) {
- size_t len;
- lua_rawgeti(L,-2,2);
- (void)lua_tolstring(L,-1,&len);
- lua_pop(L,1);
- if (len>0) { l = l + 5 + len; }
+static int count_char_packet_bytes(lua_State * L)
+{
+ register int i;
+ register int l = 0;
+ int ff = 0;
+ for (i = 1; i <= (int) lua_objlen(L, -1); i++) {
+ lua_rawgeti(L, -1, i);
+ if (lua_istable(L, -1)) {
+ lua_rawgeti(L, -1, 1);
+ if (lua_isstring(L, -1)) {
+ char *s = (char *) lua_tostring(L, -1);
+ if (luaS_ptr_eq(s, font)) {
+ l += 5;
+ ff = 1;
+ } else if (luaS_ptr_eq(s, char)) {
+ if (ff == 0) {
+ l += 5;
+ }
+ l += 5;
+ ff = 1;
+ } else if (luaS_ptr_eq(s, slot)) {
+ l += 10;
+ ff = 1;
+ } else if (luaS_ptr_eq(s, comment)) {;
+ } else if (luaS_ptr_eq(s, push) || luaS_ptr_eq(s, pop)) {
+ l++;
+ } else if (luaS_ptr_eq(s, rule)) {
+ l += 9;
+ } else if (luaS_ptr_eq(s, right) ||
+ luaS_ptr_eq(s, node) || luaS_ptr_eq(s, down)) {
+ l += 5;
+ } else if (luaS_ptr_eq(s, special)) {
+ size_t len;
+ lua_rawgeti(L, -2, 2);
+ (void) lua_tolstring(L, -1, &len);
+ lua_pop(L, 1);
+ if (len > 0) {
+ l = l + 5 + len;
+ }
+ } else if (luaS_ptr_eq(s, image)) {
+ l += 5;
+ } else {
+ fprintf(stdout, "unknown packet command %s!\n", s);
+ }
+ } else {
+ fprintf(stdout, "no packet command!\n");
+ }
+ lua_pop(L, 1); /* command name */
}
- else { fprintf(stdout,"unknown packet command %s!\n",s); }
- } else {
- fprintf(stdout,"no packet command!\n");
- }
- lua_pop(L,1); /* command name */
- }
- lua_pop(L,1); /* item */
- }
- return l;
+ lua_pop(L, 1); /* item */
+ }
+ return l;
}
-scaled
-sp_to_dvi (halfword sp, halfword atsize) {
- double result, mult;
- mult = (double)(atsize>>16);
- result = (sp << 4);
- return floor (result/mult );
+scaled sp_to_dvi(halfword sp, halfword atsize)
+{
+ double result, mult;
+ mult = (double) (atsize / 65536.0);
+ result = (double) (sp * 16.0);
+ return floor(result / mult);
}
static void
-read_char_packets (lua_State *L, integer *l_fonts, charinfo *co, int atsize) {
- int i, n, m;
- size_t l;
- int cmd;
- char *s;
- real_eight_bits *cpackets;
- int ff = 0;
- int np = 0;
- int max_f = 0;
- int pc = count_char_packet_bytes (L);
- if (pc<=0)
- return;
- assert(l_fonts != NULL);
- assert(l_fonts[1] != 0);
- while (l_fonts[(max_f+1)]!=0)
- max_f++;
-
- cpackets = xmalloc(pc+1);
- for (i=1;i<=lua_objlen(L,-1);i++) {
- lua_rawgeti(L,-1,i);
- if (lua_istable(L,-1)) {
- /* fetch the command code */
- lua_rawgeti(L,-1,1);
- if (lua_isstring(L,-1)) {
- s = (char *)lua_tostring(L,-1);
- cmd = 0;
- if (luaS_ptr_eq(s,font)) {
- cmd = packet_font_code;
- } else if (luaS_ptr_eq(s,char)) {
- cmd = packet_char_code;
- if (ff==0) {
- append_packet(packet_font_code);
- ff = l_fonts[1];
- do_store_four(ff);
- }
- } else if (luaS_ptr_eq(s,slot)) {
- cmd = packet_nop_code;
- lua_rawgeti(L,-2,2); n = lua_tointeger(L,-1);
- ff = (n>max_f ? l_fonts[1] : l_fonts[n]);
- lua_rawgeti(L,-3,3); n = lua_tointeger(L,-1);
- lua_pop(L,2);
- append_packet(packet_font_code);
- do_store_four(ff);
- append_packet(packet_char_code);
- do_store_four(n);
- }
- else if (luaS_ptr_eq(s,comment)) { cmd = packet_nop_code; }
- else if (luaS_ptr_eq(s,node)) { cmd = packet_node_code; }
- else if (luaS_ptr_eq(s,push)) { cmd = packet_push_code; }
- else if (luaS_ptr_eq(s,pop)) { cmd = packet_pop_code; }
- else if (luaS_ptr_eq(s,rule)) { cmd = packet_rule_code; }
- else if (luaS_ptr_eq(s,right)) { cmd = packet_right_code; }
- else if (luaS_ptr_eq(s,down)) { cmd = packet_down_code; }
- else if (luaS_ptr_eq(s,special)) { cmd = packet_special_code; }
-
- switch(cmd) {
- case packet_push_code:
- case packet_pop_code:
- append_packet(cmd);
- break;
- case packet_font_code:
- append_packet(cmd);
- lua_rawgeti(L,-2,2);
- n = lua_tointeger(L,-1);
- ff = (n>max_f ? l_fonts[1] : l_fonts[n]);
- do_store_four(ff);
- lua_pop(L,1);
- break;
- case packet_node_code:
- append_packet(cmd);
- lua_rawgeti(L,-2,2);
- n = copy_node_list(nodelist_from_lua(L));
- do_store_four(n);
- lua_pop(L,1);
- break;
- case packet_char_code:
- append_packet(cmd);
- lua_rawgeti(L,-2,2);
- n = lua_tointeger(L,-1);
- do_store_four(n);
- lua_pop(L,1);
- break;
- case packet_right_code:
- case packet_down_code:
- append_packet(cmd);
- lua_rawgeti(L,-2,2);
- n = lua_tointeger(L,-1);
- do_store_four(sp_to_dvi(n,atsize));
- lua_pop(L,1);
- break;
- case packet_rule_code:
- append_packet(cmd);
- lua_rawgeti(L,-2,2);
- n = lua_tointeger(L,-1);
- do_store_four(sp_to_dvi(n,atsize));
- lua_rawgeti(L,-3,3);
- n = lua_tointeger(L,-1);
- do_store_four(sp_to_dvi(n,atsize));
- lua_pop(L,2);
- break;
- case packet_special_code:
- append_packet(cmd);
- lua_rawgeti(L,-2,2);
- s = (char *)lua_tolstring(L,-1,&l);
- if (l>0) {
- do_store_four(l);
- m = (int)l;
- while(m>0) {
- n = *s++;
- m--;
- append_packet(n);
+read_char_packets(lua_State * L, integer * l_fonts, charinfo * co, int atsize)
+{
+ int i, n, m;
+ size_t l;
+ int cmd;
+ char *s;
+ real_eight_bits *cpackets;
+ int ff = 0;
+ int np = 0;
+ int max_f = 0;
+ int pc = count_char_packet_bytes(L);
+ if (pc <= 0)
+ return;
+ assert(l_fonts != NULL);
+ assert(l_fonts[1] != 0);
+ while (l_fonts[(max_f + 1)] != 0)
+ max_f++;
+
+ cpackets = xmalloc(pc + 1);
+ for (i = 1; i <= (int) lua_objlen(L, -1); i++) {
+ lua_rawgeti(L, -1, i);
+ if (lua_istable(L, -1)) {
+ /* fetch the command code */
+ lua_rawgeti(L, -1, 1);
+ if (lua_isstring(L, -1)) {
+ s = (char *) lua_tostring(L, -1);
+ cmd = 0;
+ if (luaS_ptr_eq(s, font)) {
+ cmd = packet_font_code;
+ } else if (luaS_ptr_eq(s, char)) {
+ cmd = packet_char_code;
+ if (ff == 0) {
+ append_packet(packet_font_code);
+ ff = l_fonts[1];
+ do_store_four(ff);
+ }
+ } else if (luaS_ptr_eq(s, slot)) {
+ cmd = packet_nop_code;
+ lua_rawgeti(L, -2, 2);
+ n = lua_tointeger(L, -1);
+ ff = (n > max_f ? l_fonts[1] : l_fonts[n]);
+ lua_rawgeti(L, -3, 3);
+ n = lua_tointeger(L, -1);
+ lua_pop(L, 2);
+ append_packet(packet_font_code);
+ do_store_four(ff);
+ append_packet(packet_char_code);
+ do_store_four(n);
+ } else if (luaS_ptr_eq(s, comment)) {
+ cmd = packet_nop_code;
+ } else if (luaS_ptr_eq(s, node)) {
+ cmd = packet_node_code;
+ } else if (luaS_ptr_eq(s, push)) {
+ cmd = packet_push_code;
+ } else if (luaS_ptr_eq(s, pop)) {
+ cmd = packet_pop_code;
+ } else if (luaS_ptr_eq(s, rule)) {
+ cmd = packet_rule_code;
+ } else if (luaS_ptr_eq(s, right)) {
+ cmd = packet_right_code;
+ } else if (luaS_ptr_eq(s, down)) {
+ cmd = packet_down_code;
+ } else if (luaS_ptr_eq(s, special)) {
+ cmd = packet_special_code;
+ } else if (luaS_ptr_eq(s, image)) {
+ cmd = packet_image_code;
+ }
+
+ switch (cmd) {
+ case packet_push_code:
+ case packet_pop_code:
+ append_packet(cmd);
+ break;
+ case packet_font_code:
+ append_packet(cmd);
+ lua_rawgeti(L, -2, 2);
+ n = lua_tointeger(L, -1);
+ ff = (n > max_f ? l_fonts[1] : l_fonts[n]);
+ do_store_four(ff);
+ lua_pop(L, 1);
+ break;
+ case packet_node_code:
+ append_packet(cmd);
+ lua_rawgeti(L, -2, 2);
+ n = copy_node_list(nodelist_from_lua(L));
+ do_store_four(n);
+ lua_pop(L, 1);
+ break;
+ case packet_char_code:
+ append_packet(cmd);
+ lua_rawgeti(L, -2, 2);
+ n = lua_tointeger(L, -1);
+ do_store_four(n);
+ lua_pop(L, 1);
+ break;
+ case packet_right_code:
+ case packet_down_code:
+ append_packet(cmd);
+ lua_rawgeti(L, -2, 2);
+ n = lua_tointeger(L, -1);
+ do_store_four(sp_to_dvi(n, atsize));
+ lua_pop(L, 1);
+ break;
+ case packet_rule_code:
+ append_packet(cmd);
+ lua_rawgeti(L, -2, 2);
+ n = lua_tointeger(L, -1);
+ do_store_four(sp_to_dvi(n, atsize));
+ lua_rawgeti(L, -3, 3);
+ n = lua_tointeger(L, -1);
+ do_store_four(sp_to_dvi(n, atsize));
+ lua_pop(L, 2);
+ break;
+ case packet_special_code:
+ append_packet(cmd);
+ lua_rawgeti(L, -2, 2);
+ s = (char *) lua_tolstring(L, -1, &l);
+ if (l > 0) {
+ do_store_four(l);
+ m = (int) l;
+ while (m > 0) {
+ n = *s++;
+ m--;
+ append_packet(n);
+ }
+ }
+ lua_pop(L, 1);
+ 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_call(L, 1, 1);
+ } /* img ... */
+ luaL_checkudata(L, -1, TYPE_IMG); /* img ... --- just typecheck */
+ n = luaL_ref(L, LUA_GLOBALSINDEX); /* ... */
+ do_store_four(n);
+ break;
+ case packet_nop_code:
+ break;
+ default:
+ fprintf(stdout,
+ "Unknown char packet code %s (char %d in font %s)\n",
+ s, (int) c, font_name(f));
+ }
}
- }
- lua_pop(L,1);
- break;
- case packet_nop_code:
- break;
- default:
- fprintf(stdout,"Unknown char packet code %s (char %d in font %s)\n",s,(int)c,font_name(f));
+ lua_pop(L, 1); /* command code */
+ } else {
+ fprintf(stdout,
+ "Found a `commands' item that is not a table (char %d in font %s)\n",
+ (int) c, font_name(f));
}
- }
- lua_pop(L,1); /* command code */
- } else {
- fprintf(stdout,"Found a `commands' item that is not a table (char %d in font %s)\n",(int)c,font_name(f));
+ lua_pop(L, 1); /* command table */
}
- lua_pop(L,1); /* command table */
- }
- append_packet(packet_end_code);
- set_charinfo_packets(co,cpackets);
- return;
+ append_packet(packet_end_code);
+ set_charinfo_packets(co, cpackets);
+ return;
}
-static void
-read_lua_cidinfo (lua_State *L, int f) {
- int i;
- char *s;
- lua_getfield(L,-1,"cidinfo");
- if (lua_istable(L,-1)) {
- i = numeric_field(L,"version",0);
- set_font_cidversion(f,i);
- i = numeric_field(L,"supplement",0);
- set_font_cidsupplement(f,i);
- s = string_field(L,"registry","Adobe"); /* Adobe-Identity-0 */
- set_font_cidregistry(f,s);
- s = string_field(L,"ordering","Identity");
- set_font_cidordering(f,s);
- }
- lua_pop(L,1);
+static void read_lua_cidinfo(lua_State * L, int f)
+{
+ int i;
+ char *s;
+ lua_getfield(L, -1, "cidinfo");
+ if (lua_istable(L, -1)) {
+ i = numeric_field(L, "version", 0);
+ set_font_cidversion(f, i);
+ i = numeric_field(L, "supplement", 0);
+ set_font_cidsupplement(f, i);
+ s = string_field(L, "registry", "Adobe"); /* Adobe-Identity-0 */
+ set_font_cidregistry(f, s);
+ s = string_field(L, "ordering", "Identity");
+ set_font_cidordering(f, s);
+ }
+ lua_pop(L, 1);
}
-static void
-read_lua_parameters (lua_State *L, int f) {
- int i, n;
- char *s;
- lua_getfield(L,-1,"parameters");
- if (lua_istable(L,-1)) {
- /* the number of parameters is the max(IntegerKeys(L)),7) */
- n = 7;
- lua_pushnil(L); /* first key */
- while (lua_next(L, -2) != 0) {
- if (lua_isnumber(L,-2)) {
- i = lua_tonumber(L,-2);
- if (i > n) n = i;
- }
- lua_pop(L,1); /* pop value */
- }
- if (n>7) set_font_params(f,n);
- /* sometimes it is handy to have all integer keys */
- for (i=1;i<=7;i++) {
- lua_rawgeti(L,-1,i);
- if (lua_isnumber(L,-1)) {
- n = lua_roundnumber(L,-1);
- set_font_param(f,i, n);
- }
- lua_pop(L,1);
- }
- lua_pushnil(L); /* first key */
- while (lua_next(L, -2) != 0) {
- if (lua_isnumber(L,-2)) {
- i = lua_tointeger(L,-2);
- if (i>=8) {
- n = (lua_isnumber(L,-1) ? lua_roundnumber(L,-1) : 0);
- set_font_param(f,i, n);
+static void read_lua_parameters(lua_State * L, int f)
+{
+ int i, n;
+ char *s;
+ lua_getfield(L, -1, "parameters");
+ if (lua_istable(L, -1)) {
+ /* the number of parameters is the max(IntegerKeys(L)),7) */
+ n = 7;
+ lua_pushnil(L); /* first key */
+ while (lua_next(L, -2) != 0) {
+ if (lua_isnumber(L, -2)) {
+ i = lua_tonumber(L, -2);
+ if (i > n)
+ n = i;
+ }
+ lua_pop(L, 1); /* pop value */
}
- } else if (lua_isstring(L,-2)) {
- s = (char *)lua_tostring(L,-2);
- n = (lua_isnumber(L,-1) ? lua_roundnumber(L,-1) : 0);
- if (luaS_ptr_eq(s,slant)) { set_font_param(f,slant_code,n); }
- else if (luaS_ptr_eq(s,space)) { set_font_param(f,space_code,n); }
- else if (luaS_ptr_eq(s,space_stretch)) { set_font_param(f,space_stretch_code,n); }
- else if (luaS_ptr_eq(s,space_shrink)) { set_font_param(f,space_shrink_code,n); }
- else if (luaS_ptr_eq(s,x_height)) { set_font_param(f,x_height_code,n); }
- else if (luaS_ptr_eq(s,quad)) { set_font_param(f,quad_code,n); }
- else if (luaS_ptr_eq(s,extra_space)) { set_font_param(f,extra_space_code,n); }
- }
- lua_pop(L,1);
- }
- }
- lua_pop(L,1);
+ if (n > 7)
+ set_font_params(f, n);
+ /* sometimes it is handy to have all integer keys */
+ for (i = 1; i <= 7; i++) {
+ lua_rawgeti(L, -1, i);
+ if (lua_isnumber(L, -1)) {
+ n = lua_roundnumber(L, -1);
+ set_font_param(f, i, n);
+ }
+ lua_pop(L, 1);
+ }
+ lua_pushnil(L); /* first key */
+ while (lua_next(L, -2) != 0) {
+ if (lua_isnumber(L, -2)) {
+ i = lua_tointeger(L, -2);
+ if (i >= 8) {
+ n = (lua_isnumber(L, -1) ? lua_roundnumber(L, -1) : 0);
+ set_font_param(f, i, n);
+ }
+ } else if (lua_isstring(L, -2)) {
+ s = (char *) lua_tostring(L, -2);
+ n = (lua_isnumber(L, -1) ? lua_roundnumber(L, -1) : 0);
+ if (luaS_ptr_eq(s, slant)) {
+ set_font_param(f, slant_code, n);
+ } else if (luaS_ptr_eq(s, space)) {
+ set_font_param(f, space_code, n);
+ } else if (luaS_ptr_eq(s, space_stretch)) {
+ set_font_param(f, space_stretch_code, n);
+ } else if (luaS_ptr_eq(s, space_shrink)) {
+ set_font_param(f, space_shrink_code, n);
+ } else if (luaS_ptr_eq(s, x_height)) {
+ set_font_param(f, x_height_code, n);
+ } else if (luaS_ptr_eq(s, quad)) {
+ set_font_param(f, quad_code, n);
+ } else if (luaS_ptr_eq(s, extra_space)) {
+ set_font_param(f, extra_space_code, n);
+ }
+ }
+ lua_pop(L, 1);
+ }
+ }
+ lua_pop(L, 1);
}
-
-void
-font_char_from_lua (lua_State *L, internal_font_number f, integer i, integer *l_fonts) {
- int k,r,t;
- charinfo *co;
- kerninfo *ckerns;
- liginfo *cligs;
- scaled j;
- char *s;
- int nl = 0; /* number of ligature table items */
- int nk = 0; /* number of kern table items */
- int ctr = 0;
- int atsize = font_size(f);
- if (lua_istable(L,-1)) {
- co = get_charinfo(f,i);
- set_charinfo_tag (co,0);
- j = n_numeric_field(L,luaS_width_index,0); set_charinfo_width (co,j);
- j = n_numeric_field(L,luaS_height_index,0); set_charinfo_height (co,j);
- j = n_numeric_field(L,luaS_depth_index,0); set_charinfo_depth (co,j);
- j = n_numeric_field(L,luaS_italic_index,0); set_charinfo_italic (co,j);
- j = n_numeric_field(L,luaS_index_index,0); set_charinfo_index(co,j);
- j = n_numeric_field(L,luaS_expansion_factor_index,0); set_charinfo_ef(co,j);
- j = n_numeric_field(L,luaS_left_protruding_index,0); set_charinfo_lp(co,j);
- j = n_numeric_field(L,luaS_right_protruding_index,0); set_charinfo_rp(co,j);
- k = n_boolean_field(L,luaS_used_index,0); set_charinfo_used(co,k);
- s = n_string_field (L,luaS_name_index,NULL); set_charinfo_name(co,s);
- s = n_string_field (L,luaS_tounicode_index,NULL); set_charinfo_tounicode(co,s);
- k = n_numeric_field(L,luaS_next_index,-1);
- if (k>=0) {
- set_charinfo_tag (co,list_tag);
- set_charinfo_remainder (co,k);
- }
- lua_getfield(L,-1,"extensible");
- if (lua_istable(L,-1)){
- int top, bot,mid, rep;
- top = n_numeric_field(L,luaS_top_index,0);
- bot = n_numeric_field(L,luaS_bot_index,0);
- mid = n_numeric_field(L,luaS_mid_index,0);
- rep = n_numeric_field(L,luaS_rep_index,0);
- if (top != 0 || bot != 0 || mid != 0 || rep != 0) {
- set_charinfo_tag (co,ext_tag);
- set_charinfo_extensible (co,top,bot,mid,rep);
- } else {
- pdftex_warn("lua-loaded font %s char [%d] has an invalid extensible field!",font_name(f),(int)i);
- }
- }
- lua_pop(L,1);
-
- nk = count_hash_items(L,luaS_index(kerns));
- if (nk>0) {
- ckerns = xcalloc((nk+1),sizeof(kerninfo));
- lua_rawgeti(L,LUA_REGISTRYINDEX,luaS_index(kerns));
- lua_rawget(L,-2);
- if (lua_istable(L,-1)) { /* there are kerns */
- ctr = 0;
+
+static void read_lua_math_parameters(lua_State * L, int f)
+{
+ int i = 0, n = 0;
+ lua_getfield(L, -1, "MathConstants");
+ if (lua_istable(L, -1)) {
lua_pushnil(L);
while (lua_next(L, -2) != 0) {
- k = non_boundarychar;
- if (lua_isnumber(L,-2)) {
- k = lua_tonumber(L,-2); /* adjacent char */
- if (k<0)
- k = non_boundarychar;
- } else if (lua_isstring(L,-2)) {
- s = (char *)lua_tostring(L,-2);
- if (luaS_ptr_eq(s,right_boundary)) {
- k = right_boundarychar;
- if (!has_right_boundary(f))
- set_right_boundary(f,get_charinfo(f,right_boundarychar));
+ if (lua_isnumber(L, -2)) {
+ i = lua_tonumber(L, -2);
+ } else if (lua_isstring(L, -2)) {
+ i = luaL_checkoption(L, -2, NULL, MATH_param_names);
+ }
+ n = lua_tonumber(L, -1);
+ if (i != 0) {
+ set_font_math_param(f, i, n);
}
- }
- j = lua_roundnumber(L,-1); /* movement */
- if (k!=non_boundarychar) {
- set_kern_item(ckerns[ctr],k,j);
- ctr++;
- } else {
- pdftex_warn("lua-loaded font %s char [%d] has an invalid kern field!",font_name(f),(int)i);
- }
- lua_pop(L,1);
+ lua_pop(L, 1); /* pop value */
}
- /* guard against empty tables */
- if (ctr>0) {
- set_kern_item(ckerns[ctr],end_kern,0);
- set_charinfo_kerns(co,ckerns);
- } else {
- pdftex_warn("lua-loaded font %s char [%d] has an invalid kerns field!",font_name(f),(int)i);
+ }
+ lua_pop(L, 1);
+}
+
+
+void
+font_char_from_lua(lua_State * L, internal_font_number f, integer i,
+ integer * l_fonts)
+{
+ int k, r, t;
+ charinfo *co;
+ kerninfo *ckerns;
+ liginfo *cligs;
+ scaled j;
+ char *s;
+ int nl = 0; /* number of ligature table items */
+ int nk = 0; /* number of kern table items */
+ int ctr = 0;
+ int atsize = font_size(f);
+ if (lua_istable(L, -1)) {
+ co = get_charinfo(f, i);
+ set_charinfo_tag(co, 0);
+ j = n_numeric_field(L, luaS_width_index, 0);
+ set_charinfo_width(co, j);
+ j = n_numeric_field(L, luaS_height_index, 0);
+ set_charinfo_height(co, j);
+ j = n_numeric_field(L, luaS_depth_index, 0);
+ set_charinfo_depth(co, j);
+ j = n_numeric_field(L, luaS_italic_index, 0);
+ set_charinfo_italic(co, j);
+ j = n_numeric_field(L, luaS_top_accent_index, 0);
+ set_charinfo_top_accent(co, j);
+ j = n_numeric_field(L, luaS_bot_accent_index, 0);
+ set_charinfo_bot_accent(co, j);
+ j = n_numeric_field(L, luaS_index_index, 0);
+ set_charinfo_index(co, j);
+ j = n_numeric_field(L, luaS_expansion_factor_index, 0);
+ set_charinfo_ef(co, j);
+ j = n_numeric_field(L, luaS_left_protruding_index, 0);
+ set_charinfo_lp(co, j);
+ j = n_numeric_field(L, luaS_right_protruding_index, 0);
+ set_charinfo_rp(co, j);
+ k = n_boolean_field(L, luaS_used_index, 0);
+ set_charinfo_used(co, k);
+ s = n_string_field(L, luaS_name_index, NULL);
+ set_charinfo_name(co, s);
+ s = n_string_field(L, luaS_tounicode_index, NULL);
+ set_charinfo_tounicode(co, s);
+ k = n_numeric_field(L, luaS_next_index, -1);
+ if (k >= 0) {
+ set_charinfo_tag(co, list_tag);
+ set_charinfo_remainder(co, k);
}
- }
- lua_pop(L,1);
- }
-
- /* packet commands */
- lua_getfield(L,-1,"commands");
- if (lua_istable(L,-1)){
- lua_pushnil(L); /* first key */
- if (lua_next(L, -2) != 0) {
- lua_pop(L,2);
- read_char_packets(L,(integer *)l_fonts,co,atsize);
- }
- }
- lua_pop(L,1);
-
- /* ligatures */
- nl = count_hash_items(L,luaS_index(ligatures));
-
- if (nl>0) {
- cligs = xcalloc((nl+1),sizeof(liginfo));
- lua_rawgeti(L,LUA_REGISTRYINDEX,luaS_index(ligatures));
- lua_rawget(L,-2);
- if (lua_istable(L,-1)){/* do ligs */
- ctr = 0;
- lua_pushnil(L);
- while (lua_next(L, -2) != 0) {
- k = non_boundarychar;
- if (lua_isnumber(L,-2)) {
- k = lua_tonumber(L,-2); /* adjacent char */
- if (k<0) {
- k = non_boundarychar;
+ lua_getfield(L, -1, "extensible");
+ if (lua_istable(L, -1)) {
+ int top, bot, mid, rep;
+ top = n_numeric_field(L, luaS_top_index, 0);
+ bot = n_numeric_field(L, luaS_bot_index, 0);
+ mid = n_numeric_field(L, luaS_mid_index, 0);
+ rep = n_numeric_field(L, luaS_rep_index, 0);
+ if (top != 0 || bot != 0 || mid != 0 || rep != 0) {
+ set_charinfo_tag(co, ext_tag);
+ set_charinfo_extensible(co, top, bot, mid, rep);
+ } else {
+ pdftex_warn
+ ("lua-loaded font %s char [U+%X] has an invalid extensible field!",
+ font_name(f), (int) i);
}
- } else if (lua_isstring(L,-2)) {
- s = (char *)lua_tostring(L,-2);
- if (luaS_ptr_eq(s,right_boundary)) {
- k = right_boundarychar;
- if (!has_right_boundary(f))
- set_right_boundary(f,get_charinfo(f,right_boundarychar));
+ }
+ lua_pop(L, 1);
+
+ lua_getfield(L, -1, "horiz_variants");
+ if (lua_istable(L, -1)) {
+ int glyph, startconnect, endconnect, advance, extender;
+ extinfo *h;
+ set_charinfo_tag(co, ext_tag);
+ set_charinfo_hor_variants(co, NULL);
+ for (k = 1;; k++) {
+ lua_rawgeti(L, -1, k);
+ if (lua_istable(L, -1)) {
+ glyph = n_numeric_field(L, luaS_glyph_index, 0);
+ extender = n_numeric_field(L, luaS_extender_index, 0);
+ startconnect = n_numeric_field(L, luaS_start_index, 0);
+ endconnect = n_numeric_field(L, luaS_end_index, 0);
+ advance = n_numeric_field(L, luaS_advance_index, 0);
+ h = new_variant(glyph, startconnect, endconnect, advance,
+ extender);
+ add_charinfo_hor_variant(co, h);
+ lua_pop(L, 1);
+ } else {
+ lua_pop(L, 1);
+ break;
+ }
}
- }
- r = -1;
- if (lua_istable(L,-1)) {
- r = n_numeric_field(L,luaS_char_index,-1); /* ligature */
- }
- if (r != -1 && k != non_boundarychar) {
- t = enum_field(L,"type",0,ligature_type_strings);
- set_ligature_item(cligs[ctr],(t*2)+1,k,r);
- ctr++;
- } else {
- pdftex_warn("lua-loaded font %s char [%d] has an invalid ligature field!",font_name(f),(int)i);
- }
- lua_pop(L,1); /* iterator value */
- }
- /* guard against empty tables */
- if (ctr>0) {
- set_ligature_item(cligs[ctr],0,end_ligature,0);
- set_charinfo_ligatures(co,cligs);
- } else {
- pdftex_warn("lua-loaded font %s char [%d] has an invalid ligatures field!",font_name(f),(int)i);
}
- }
- lua_pop(L,1); /* ligatures table */
+ lua_pop(L, 1);
+
+
+ lua_getfield(L, -1, "vert_variants");
+ if (lua_istable(L, -1)) {
+ int glyph, startconnect, endconnect, advance, extender;
+ extinfo *h;
+ set_charinfo_tag(co, ext_tag);
+ set_charinfo_vert_variants(co, NULL);
+ for (k = 1;; k++) {
+ lua_rawgeti(L, -1, k);
+ if (lua_istable(L, -1)) {
+ glyph = n_numeric_field(L, luaS_glyph_index, 0);
+ extender = n_numeric_field(L, luaS_extender_index, 0);
+ startconnect = n_numeric_field(L, luaS_start_index, 0);
+ endconnect = n_numeric_field(L, luaS_end_index, 0);
+ advance = n_numeric_field(L, luaS_advance_index, 0);
+ h = new_variant(glyph, startconnect, endconnect, advance,
+ extender);
+ add_charinfo_vert_variant(co, h);
+ lua_pop(L, 1);
+ } else {
+ lua_pop(L, 1);
+ break;
+ }
+ }
+ }
+ lua_pop(L, 1);
+
+ nk = count_hash_items(L, luaS_index(kerns));
+ if (nk > 0) {
+ ckerns = xcalloc((nk + 1), sizeof(kerninfo));
+ lua_rawgeti(L, LUA_REGISTRYINDEX, luaS_index(kerns));
+ lua_rawget(L, -2);
+ if (lua_istable(L, -1)) { /* there are kerns */
+ ctr = 0;
+ lua_pushnil(L);
+ while (lua_next(L, -2) != 0) {
+ k = non_boundarychar;
+ if (lua_isnumber(L, -2)) {
+ k = lua_tonumber(L, -2); /* adjacent char */
+ if (k < 0)
+ k = non_boundarychar;
+ } else if (lua_isstring(L, -2)) {
+ s = (char *) lua_tostring(L, -2);
+ if (luaS_ptr_eq(s, right_boundary)) {
+ k = right_boundarychar;
+ if (!has_right_boundary(f))
+ set_right_boundary(f,
+ get_charinfo(f,
+ right_boundarychar));
+ }
+ }
+ j = lua_roundnumber(L, -1); /* movement */
+ if (k != non_boundarychar) {
+ set_kern_item(ckerns[ctr], k, j);
+ ctr++;
+ } else {
+ pdftex_warn
+ ("lua-loaded font %s char [U+%X] has an invalid kern field!",
+ font_name(f), (int) i);
+ }
+ lua_pop(L, 1);
+ }
+ /* guard against empty tables */
+ if (ctr > 0) {
+ set_kern_item(ckerns[ctr], end_kern, 0);
+ set_charinfo_kerns(co, ckerns);
+ } else {
+ pdftex_warn
+ ("lua-loaded font %s char [U+%X] has an invalid kerns field!",
+ font_name(f), (int) i);
+ }
+ }
+ lua_pop(L, 1);
+ }
+
+ /* packet commands */
+ lua_getfield(L, -1, "commands");
+ if (lua_istable(L, -1)) {
+ lua_pushnil(L); /* first key */
+ if (lua_next(L, -2) != 0) {
+ lua_pop(L, 2);
+ read_char_packets(L, (integer *) l_fonts, co, atsize);
+ }
+ }
+ lua_pop(L, 1);
+
+ /* ligatures */
+ nl = count_hash_items(L, luaS_index(ligatures));
+
+ if (nl > 0) {
+ cligs = xcalloc((nl + 1), sizeof(liginfo));
+ lua_rawgeti(L, LUA_REGISTRYINDEX, luaS_index(ligatures));
+ lua_rawget(L, -2);
+ if (lua_istable(L, -1)) { /* do ligs */
+ ctr = 0;
+ lua_pushnil(L);
+ while (lua_next(L, -2) != 0) {
+ k = non_boundarychar;
+ if (lua_isnumber(L, -2)) {
+ k = lua_tonumber(L, -2); /* adjacent char */
+ if (k < 0) {
+ k = non_boundarychar;
+ }
+ } else if (lua_isstring(L, -2)) {
+ s = (char *) lua_tostring(L, -2);
+ if (luaS_ptr_eq(s, right_boundary)) {
+ k = right_boundarychar;
+ if (!has_right_boundary(f))
+ set_right_boundary(f,
+ get_charinfo(f,
+ right_boundarychar));
+ }
+ }
+ r = -1;
+ if (lua_istable(L, -1)) {
+ r = n_numeric_field(L, luaS_char_index, -1); /* ligature */
+ }
+ if (r != -1 && k != non_boundarychar) {
+ t = enum_field(L, "type", 0, ligature_type_strings);
+ set_ligature_item(cligs[ctr], (t * 2) + 1, k, r);
+ ctr++;
+ } else {
+ pdftex_warn
+ ("lua-loaded font %s char [U+%X] has an invalid ligature field!",
+ font_name(f), (int) i);
+ }
+ lua_pop(L, 1); /* iterator value */
+ }
+ /* guard against empty tables */
+ if (ctr > 0) {
+ set_ligature_item(cligs[ctr], 0, end_ligature, 0);
+ set_charinfo_ligatures(co, cligs);
+ } else {
+ pdftex_warn
+ ("lua-loaded font %s char [U+%X] has an invalid ligatures field!",
+ font_name(f), (int) i);
+ }
+ }
+ lua_pop(L, 1); /* ligatures table */
+ }
}
- }
}
@@ -943,203 +1286,247 @@ font_char_from_lua (lua_State *L, internal_font_number f, integer i, integer *l_
/* The caller has to fix the state of the lua stack when there is an error! */
-int
-font_from_lua (lua_State *L, int f) {
- int i,n,r,t;
- int s_top; /* lua stack top */
- int bc; /* first char index */
- int ec; /* last char index */
- char *s;
- integer *l_fonts = NULL;
- /* the table is at stack index -1 */
-
- if (luaS_width_index==0)
- init_font_string_pointers(L);
-
- s = string_field(L,"area",""); set_font_area(f,s);
- s = string_field(L,"filename",NULL); set_font_filename(f,s);
- s = string_field(L,"encodingname",NULL); set_font_encodingname(f,s);
-
- s = string_field(L,"name",NULL); set_font_name(f,s);
- s = string_field(L,"fullname",font_name(f)); set_font_fullname(f,s);
-
- if (s==NULL) {
- pdftex_fail("lua-loaded font [%d] has no name!",f);
- return false;
- }
-
- i = numeric_field(L,"designsize",655360); set_font_dsize(f,i);
- i = numeric_field(L,"size",font_dsize(f)); set_font_size(f,i);
- i = numeric_field(L,"checksum",0); set_font_checksum(f,i);
- i = numeric_field(L,"direction",0); set_font_natural_dir(f,i);
- i = numeric_field(L,"encodingbytes",0); set_font_encodingbytes(f,i);
- i = numeric_field(L,"tounicode",0); set_font_tounicode(f,i);
-
- i = numeric_field(L,"extend",0);
- if (i<-2000) i = -2000; if (i>2000) i = 2000; if (i==1000) i = 0;
- set_font_extend(f,i);
- i = numeric_field(L,"slant",0);
- if (i<-1000) i = -1000; if (i>1000) i = 1000;
- set_font_slant(f,i);
-
- i = numeric_field(L,"hyphenchar",get_default_hyphen_char()); set_hyphen_char(f,i);
- i = numeric_field(L,"skewchar",get_default_skew_char()); set_skew_char(f,i);
- i = boolean_field(L,"used",0); set_font_used(f,i);
-
- s = string_field (L,"attributes",NULL);
- if (s!=NULL && strlen(s)>0) {
- i = maketexstring(s);
- set_pdf_font_attr(f,i);
- }
-
- i = enum_field(L,"type", unknown_font_type,font_type_strings); set_font_type(f,i);
- i = enum_field(L,"format", unknown_format, font_format_strings); set_font_format(f,i);
- i = enum_field(L,"embedding",unknown_embedding,font_embedding_strings); set_font_embedding(f,i);
- 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 */
- n = count_hash_items(L,luaS_index(fonts));
- if (n>0) {
- l_fonts = xmalloc((n+2)*sizeof(integer));
- memset (l_fonts,0,(n+2)*sizeof(integer));
- lua_rawgeti(L,LUA_REGISTRYINDEX,luaS_index(fonts));
- lua_rawget(L,-2);
- for (i=1;i<=n;i++) {
- lua_rawgeti(L,-1,i);
- if (lua_istable(L,-1)) {
- lua_getfield(L,-1,"id");
- if (lua_isnumber(L,-1)) {
- l_fonts[i] = lua_tonumber(L,-1);
- lua_pop(L,2); /* pop id and entry */
- continue;
- }
- lua_pop(L,1); /* pop id */
- };
- s = NULL;
- if (lua_istable(L,-1)) {
- lua_getfield(L,-1,"name");
- if (lua_isstring(L,-1)) {
- s = (char *)lua_tostring(L,-1);
- }
- lua_pop(L,1); /* pop name */
- }
- if (s!= NULL) {
- lua_getfield(L,-1,"size");
- t = (lua_isnumber(L,-1) ? lua_roundnumber(L,-1) : -1000);
- lua_pop(L,1);
-
- /* TODO: the stack is messed up, otherwise this
- * explicit resizing would not be needed
- */
- s_top = lua_gettop(L);
- l_fonts[i] = find_font_id(s,"",t);
- lua_settop(L,s_top);
- } else {
- pdftex_fail("Invalid local font in font %s!\n", font_name(f));
- }
- lua_pop(L,1); /* pop list entry */
- }
- lua_pop(L,1); /* pop list entry */
- } else {
- if(font_type(f) == virtual_font_type) {
- pdftex_fail("Invalid local fonts in font %s!\n", font_name(f));
- } else {
- l_fonts = xmalloc(3*sizeof(integer));
- l_fonts[0] = 0;
- l_fonts[1] = f;
- l_fonts[2] = 0;
- }
- }
-
- /* parameters */
- read_lua_parameters(L,f);
- read_lua_cidinfo(L,f);
-
- /* characters */
- lua_getfield(L,-1,"characters");
- if (lua_istable(L,-1)) {
- /* find the array size values */
- ec = 0; bc = -1;
- lua_pushnil(L); /* first key */
- while (lua_next(L, -2) != 0) {
- if (lua_isnumber(L,-2)) {
- i = lua_tointeger(L,-2);
- if (i>=0) {
- if (lua_istable(L,-1)) {
- if (i>ec) ec = i;
- if (bc<0) bc = i;
- if (bc>=0 && i<bc) bc = i;
- }
+int font_from_lua(lua_State * L, int f)
+{
+ int i, n, r, t;
+ int s_top; /* lua stack top */
+ int bc; /* first char index */
+ int ec; /* last char index */
+ char *s;
+ integer *l_fonts = NULL;
+ /* the table is at stack index -1 */
+
+ if (luaS_width_index == 0)
+ init_font_string_pointers(L);
+
+ s = string_field(L, "area", "");
+ set_font_area(f, s);
+ s = string_field(L, "filename", NULL);
+ set_font_filename(f, s);
+ s = string_field(L, "encodingname", NULL);
+ set_font_encodingname(f, s);
+
+ s = string_field(L, "name", NULL);
+ set_font_name(f, s);
+ s = string_field(L, "fullname", font_name(f));
+ set_font_fullname(f, s);
+
+ if (s == NULL) {
+ pdftex_fail("lua-loaded font [%d] has no name!", f);
+ return false;
+ }
+
+ i = numeric_field(L, "designsize", 655360);
+ set_font_dsize(f, i);
+ i = numeric_field(L, "size", font_dsize(f));
+ set_font_size(f, i);
+ i = numeric_field(L, "checksum", 0);
+ set_font_checksum(f, i);
+ i = numeric_field(L, "direction", 0);
+ set_font_natural_dir(f, i);
+ i = numeric_field(L, "encodingbytes", 0);
+ set_font_encodingbytes(f, i);
+ i = numeric_field(L, "tounicode", 0);
+ set_font_tounicode(f, i);
+
+ i = numeric_field(L, "extend", 0);
+ if (i < -2000)
+ i = -2000;
+ if (i > 2000)
+ i = 2000;
+ if (i == 1000)
+ i = 0;
+ set_font_extend(f, i);
+ i = numeric_field(L, "slant", 0);
+ if (i < -1000)
+ i = -1000;
+ if (i > 1000)
+ i = 1000;
+ set_font_slant(f, i);
+
+ i = numeric_field(L, "hyphenchar", get_default_hyphen_char());
+ set_hyphen_char(f, i);
+ i = numeric_field(L, "skewchar", get_default_skew_char());
+ set_skew_char(f, i);
+ i = boolean_field(L, "used", 0);
+ set_font_used(f, i);
+
+ s = string_field(L, "attributes", NULL);
+ if (s != NULL && strlen(s) > 0) {
+ i = maketexstring(s);
+ set_pdf_font_attr(f, i);
+ }
+
+ i = enum_field(L, "type", unknown_font_type, font_type_strings);
+ set_font_type(f, i);
+ i = enum_field(L, "format", unknown_format, font_format_strings);
+ set_font_format(f, i);
+ i = enum_field(L, "embedding", unknown_embedding, font_embedding_strings);
+ set_font_embedding(f, i);
+ 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 */
+ n = count_hash_items(L, luaS_index(fonts));
+ if (n > 0) {
+ l_fonts = xmalloc((n + 2) * sizeof(integer));
+ memset(l_fonts, 0, (n + 2) * sizeof(integer));
+ lua_rawgeti(L, LUA_REGISTRYINDEX, luaS_index(fonts));
+ lua_rawget(L, -2);
+ for (i = 1; i <= n; i++) {
+ lua_rawgeti(L, -1, i);
+ if (lua_istable(L, -1)) {
+ lua_getfield(L, -1, "id");
+ if (lua_isnumber(L, -1)) {
+ l_fonts[i] = lua_tonumber(L, -1);
+ lua_pop(L, 2); /* pop id and entry */
+ continue;
+ }
+ lua_pop(L, 1); /* pop id */
+ };
+ s = NULL;
+ if (lua_istable(L, -1)) {
+ lua_getfield(L, -1, "name");
+ if (lua_isstring(L, -1)) {
+ s = (char *) lua_tostring(L, -1);
+ }
+ lua_pop(L, 1); /* pop name */
+ }
+ if (s != NULL) {
+ lua_getfield(L, -1, "size");
+ t = (lua_isnumber(L, -1) ? lua_roundnumber(L, -1) : -1000);
+ lua_pop(L, 1);
+
+ /* TODO: the stack is messed up, otherwise this
+ * explicit resizing would not be needed
+ */
+ s_top = lua_gettop(L);
+ if (strcmp(font_name(f), s) == 0)
+ l_fonts[i] = f;
+ else
+ l_fonts[i] = find_font_id(s, "", t);
+ lua_settop(L, s_top);
+ } else {
+ pdftex_fail("Invalid local font in font %s!\n", font_name(f));
+ }
+ lua_pop(L, 1); /* pop list entry */
}
- }
- lua_pop(L, 1);
- }
-
- if (bc != -1) {
- /* fprintf(stdout,"defined a font at %d with %d-%d\n",f,bc,ec); */
- set_font_bc(f,bc);
- set_font_ec(f,ec);
- lua_pushnil(L); /* first key */
- while (lua_next(L, -2) != 0) {
- if (lua_isnumber(L,-2)) {
- i = lua_tonumber(L,-2);
- if (i>=0) {
- font_char_from_lua(L,f, i, l_fonts);
- }
- } else if (lua_isstring(L,-2)) {
- s = (char *)lua_tostring(L,-2);
- if (luaS_ptr_eq(s,left_boundary)) {
- font_char_from_lua(L,f, left_boundarychar, l_fonts);
- } else if (luaS_ptr_eq(s,right_boundary)) {
- font_char_from_lua(L,f, right_boundarychar, l_fonts);
- }
+ lua_pop(L, 1); /* pop list entry */
+ } else {
+ if (font_type(f) == virtual_font_type) {
+ pdftex_fail("Invalid local fonts in font %s!\n", font_name(f));
+ } else {
+ l_fonts = xmalloc(3 * sizeof(integer));
+ l_fonts[0] = 0;
+ l_fonts[1] = f;
+ l_fonts[2] = 0;
}
- lua_pop(L, 1);
- }
- lua_pop(L, 1);
-
- /* handle font expansion last: the |copy_font| routine is called eventually,
- and that needs to know |bc| and |ec|. */
- if (font_type(f)!=virtual_font_type) {
- int fstep = numeric_field(L,"step",0);
- if (fstep<0) fstep = 0;
- if (fstep>100) fstep = 100;
- if (fstep!=0) {
- int fshrink = numeric_field(L,"shrink",0);
- int fstretch = numeric_field(L,"stretch",0);
- int fexpand = boolean_field(L,"auto_expand",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, fexpand, fstretch, fshrink, fstep, 0);
- }
- }
-
- } else { /* jikes, no characters */
- pdftex_warn("lua-loaded font [%d] (%s) has no characters!",f, font_name(f));
}
+ /* parameters */
+ read_lua_parameters(L, f);
+ read_lua_math_parameters(L, f);
+ read_lua_cidinfo(L, f);
+
+ /* characters */
+ lua_getfield(L, -1, "characters");
+ if (lua_istable(L, -1)) {
+ /* find the array size values */
+ ec = 0;
+ bc = -1;
+ lua_pushnil(L); /* first key */
+ while (lua_next(L, -2) != 0) {
+ if (lua_isnumber(L, -2)) {
+ i = lua_tointeger(L, -2);
+ if (i >= 0) {
+ if (lua_istable(L, -1)) {
+ if (i > ec)
+ ec = i;
+ if (bc < 0)
+ bc = i;
+ if (bc >= 0 && i < bc)
+ bc = i;
+ }
+ }
+ }
+ lua_pop(L, 1);
+ }
+
+ if (bc != -1) {
+ /* fprintf(stdout,"defined a font at %d with %d-%d\n",f,bc,ec); */
+ set_font_bc(f, bc);
+ set_font_ec(f, ec);
+ lua_pushnil(L); /* first key */
+ while (lua_next(L, -2) != 0) {
+ if (lua_isnumber(L, -2)) {
+ i = lua_tonumber(L, -2);
+ if (i >= 0) {
+ font_char_from_lua(L, f, i, l_fonts);
+ }
+ } else if (lua_isstring(L, -2)) {
+ s = (char *) lua_tostring(L, -2);
+ if (luaS_ptr_eq(s, left_boundary)) {
+ font_char_from_lua(L, f, left_boundarychar, l_fonts);
+ } else if (luaS_ptr_eq(s, right_boundary)) {
+ font_char_from_lua(L, f, right_boundarychar, l_fonts);
+ }
+ }
+ lua_pop(L, 1);
+ }
+ lua_pop(L, 1);
+
+ /* handle font expansion last: the |copy_font| routine is called eventually,
+ and that needs to know |bc| and |ec|. */
+ if (font_type(f) != virtual_font_type) {
+ int fstep = numeric_field(L, "step", 0);
+ if (fstep < 0)
+ fstep = 0;
+ if (fstep > 100)
+ fstep = 100;
+ if (fstep != 0) {
+ int fshrink = numeric_field(L, "shrink", 0);
+ int fstretch = numeric_field(L, "stretch", 0);
+ int fexpand = boolean_field(L, "auto_expand", 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, fexpand, fstretch, fshrink, fstep, 0);
+ }
+ }
+
+ } else { /* jikes, no characters */
+ pdftex_warn("lua-loaded font [%d] (%s) has no characters!", f,
+ font_name(f));
+ }
+
#if SAVE_REF
- r = luaL_ref(Luas[0],LUA_REGISTRYINDEX); /* pops the table */
- set_font_cache_id(f,r);
+ r = luaL_ref(Luas, LUA_REGISTRYINDEX); /* pops the table */
+ set_font_cache_id(f, r);
#else
- lua_pop(Luas[0],1);
+ lua_pop(Luas, 1);
#endif
- } else { /* jikes, no characters */
- pdftex_warn("lua-loaded font [%d] (%s) has no character table!",f, font_name(f));
- }
+ } else { /* jikes, no characters */
+ pdftex_warn("lua-loaded font [%d] (%s) has no character table!", f,
+ font_name(f));
+ }
- if (l_fonts!=NULL)
- free(l_fonts);
- return true;
+ if (l_fonts != NULL)
+ free(l_fonts);
+ return true;
}
/* ====================================================================
@@ -1151,393 +1538,423 @@ font_from_lua (lua_State *L, int f) {
#define assert_disc(a) \
assert(pre_break(a)!=null); /* expect head_node */ \
- assert(type(pre_break(a))==nesting_node); \
+ assert(type(pre_break(a))==nesting_node); \
assert((vlink_pre_break(a)==null && tlink_pre_break(a)==null) || tail_of_list(vlink_pre_break(a))==tlink_pre_break(a)); \
assert(post_break(a)!=null); /* expect head_node */ \
- assert(type(post_break(a))==nesting_node); \
+ assert(type(post_break(a))==nesting_node); \
assert((vlink_post_break(a)==null && tlink_post_break(a)==null) || tail_of_list(vlink_post_break(a))==tlink_post_break(a)); \
- assert(no_break(a)!=null); /* expect head_node */ \
- assert(type(no_break(a))==nesting_node); \
- assert((vlink_no_break(a)==null && tlink_no_break(a)==null) || tail_of_list(vlink_no_break(a))==tlink_no_break(a));
-
-static void
-nesting_append (halfword nest, halfword newn) {
- halfword tail = tlink(nest);
- assert(alink(nest)==null);
- assert(vlink(newn)==null);
- assert(alink(newn)==null);
- if (tail==null) {
- assert(vlink(nest)==null);
- couple_nodes(nest,newn);
- } else {
- assert(vlink(tail)==null);
- assert(tail_of_list(vlink(nest))==tail);
- couple_nodes(tail,newn);
- }
- tlink(nest) = newn;
+ assert(no_break(a)!=null); /* expect head_node */ \
+ assert(type(no_break(a))==nesting_node); \
+ assert((vlink_no_break(a)==null && tlink_no_break(a)==null) || tail_of_list(vlink_no_break(a))==tlink_no_break(a));
+
+static void nesting_append(halfword nest, halfword newn)
+{
+ halfword tail = tlink(nest);
+ assert(alink(nest) == null);
+ assert(vlink(newn) == null);
+ assert(alink(newn) == null);
+ if (tail == null) {
+ assert(vlink(nest) == null);
+ couple_nodes(nest, newn);
+ } else {
+ assert(vlink(tail) == null);
+ assert(tail_of_list(vlink(nest)) == tail);
+ couple_nodes(tail, newn);
+ }
+ tlink(nest) = newn;
}
-static void
-nesting_prepend (halfword nest, halfword newn) {
- halfword head = vlink(nest);
- assert(alink(nest)==null);
- assert(vlink(newn)==null);
- assert(alink(newn)==null);
- couple_nodes(nest,newn);
- if (head==null) {
- assert(tlink(nest)==null);
- tlink(nest) = newn;
- } else {
- assert(alink(head)==nest);
- assert(tail_of_list(head)==tlink(nest));
- couple_nodes(newn,head);
- }
+static void nesting_prepend(halfword nest, halfword newn)
+{
+ halfword head = vlink(nest);
+ assert(alink(nest) == null);
+ assert(vlink(newn) == null);
+ assert(alink(newn) == null);
+ couple_nodes(nest, newn);
+ if (head == null) {
+ assert(tlink(nest) == null);
+ tlink(nest) = newn;
+ } else {
+ assert(alink(head) == nest);
+ assert(tail_of_list(head) == tlink(nest));
+ couple_nodes(newn, head);
+ }
}
-static int
-test_ligature( liginfo *lig, halfword left, halfword right ) {
- if (type(left)!=glyph_node)
- return 0;
- assert(type(right)==glyph_node);
- if (font(left)!=font(right)) return 0;
- if (is_ghost(left) || is_ghost(right)) return 0;
- *lig = get_ligature(font(left),character(left),character(right));
- if (is_valid_ligature(*lig)) {
- return 1;
- }
- return 0;
+static int test_ligature(liginfo * lig, halfword left, halfword right)
+{
+ if (type(left) != glyph_node)
+ return 0;
+ assert(type(right) == glyph_node);
+ if (font(left) != font(right))
+ return 0;
+ if (is_ghost(left) || is_ghost(right))
+ return 0;
+ *lig = get_ligature(font(left), character(left), character(right));
+ if (is_valid_ligature(*lig)) {
+ return 1;
+ }
+ return 0;
}
-static int
-try_ligature(halfword *frst, halfword fwd) {
- halfword cur = *frst;
- liginfo lig;
- if (test_ligature(&lig,cur,fwd)) {
- int move_after = (lig_type(lig) & 0x0C)>>2;
- int keep_right = ((lig_type(lig) & 0x01) != 0);
- int keep_left = ((lig_type(lig) & 0x02) != 0);
- halfword newgl = raw_glyph_node();
- 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 ... */
- if (character(cur)<0) {
- set_is_leftboundary(newgl);
- }
- if (character(fwd)<0) {
- set_is_rightboundary(newgl);
- }
- if (character(cur)<0) {
- if (character(fwd)<0) {
- build_attribute_list(newgl);
- } else {
- add_node_attr_ref(node_attr(fwd));
- node_attr(newgl) = node_attr(fwd);
- }
- } else {
- 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 */
- /* left side */
- if (keep_left) {
- halfword new_first = copy_node(cur);
- lig_ptr(newgl) = new_first;
- couple_nodes(cur,newgl);
- if (move_after) {
- move_after--;
- cur = newgl;
- }
- } else {
- halfword prev = alink(cur);
- uncouple_node(cur);
- lig_ptr(newgl) = cur;
- assert(prev!=null);
- couple_nodes(prev,newgl);
- cur = newgl; /* as cur has disappeared */
- }
- /* right side */
- if (keep_right) {
- halfword new_second = copy_node(fwd);
- /* correct, because we _know_ lig_ptr points to _one_ node */
- couple_nodes(lig_ptr(newgl),new_second);
- couple_nodes(newgl,fwd);
- if (move_after) {
- move_after--;
- cur = fwd;
- }
- } else {
- halfword next = vlink(fwd);
- uncouple_node(fwd);
- /* correct, because we _know_ lig_ptr points to _one_ node */
- couple_nodes(lig_ptr(newgl),fwd);
- if (next!=null) {couple_nodes(newgl,next);}
- }
+static int try_ligature(halfword * frst, halfword fwd)
+{
+ halfword cur = *frst;
+ liginfo lig;
+ if (test_ligature(&lig, cur, fwd)) {
+ int move_after = (lig_type(lig) & 0x0C) >> 2;
+ int keep_right = ((lig_type(lig) & 0x01) != 0);
+ int keep_left = ((lig_type(lig) & 0x02) != 0);
+ halfword newgl = raw_glyph_node();
+ 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 ... */
+ if (character(cur) < 0) {
+ set_is_leftboundary(newgl);
+ }
+ if (character(fwd) < 0) {
+ set_is_rightboundary(newgl);
+ }
+ if (character(cur) < 0) {
+ if (character(fwd) < 0) {
+ build_attribute_list(newgl);
+ } else {
+ add_node_attr_ref(node_attr(fwd));
+ node_attr(newgl) = node_attr(fwd);
+ }
+ } else {
+ add_node_attr_ref(node_attr(cur));
+ node_attr(newgl) = node_attr(cur);
+ }
- /* check and return */
- /* assert(move_after==0);*/
- *frst = cur;
- return 1;
- }
- return 0;
+ /* 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 */
+ /* left side */
+ if (keep_left) {
+ halfword new_first = copy_node(cur);
+ lig_ptr(newgl) = new_first;
+ couple_nodes(cur, newgl);
+ if (move_after) {
+ move_after--;
+ cur = newgl;
+ }
+ } else {
+ halfword prev = alink(cur);
+ uncouple_node(cur);
+ lig_ptr(newgl) = cur;
+ assert(prev != null);
+ couple_nodes(prev, newgl);
+ cur = newgl; /* as cur has disappeared */
+ }
+ /* right side */
+ if (keep_right) {
+ halfword new_second = copy_node(fwd);
+ /* correct, because we _know_ lig_ptr points to _one_ node */
+ couple_nodes(lig_ptr(newgl), new_second);
+ couple_nodes(newgl, fwd);
+ if (move_after) {
+ move_after--;
+ cur = fwd;
+ }
+ } else {
+ halfword next = vlink(fwd);
+ uncouple_node(fwd);
+ /* correct, because we _know_ lig_ptr points to _one_ node */
+ couple_nodes(lig_ptr(newgl), fwd);
+ if (next != null) {
+ couple_nodes(newgl, next);
+ }
+ }
+
+ /* check and return */
+ /* assert(move_after==0); */
+ *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 */
-static halfword
-handle_lig_nest(halfword root, halfword cur) {
- if (cur==null) return root;
- while (vlink(cur)!=null) {
- halfword fwd = vlink(cur);
- if (type(cur)==glyph_node && type(fwd)==glyph_node &&
- font(cur)==font(fwd) && try_ligature(&cur,fwd)) continue;
- cur = vlink(cur);
- assert(vlink(alink(cur))==cur);
- }
- tlink(root) = cur;
- return root;
+static halfword handle_lig_nest(halfword root, halfword cur)
+{
+ if (cur == null)
+ return root;
+ while (vlink(cur) != null) {
+ halfword fwd = vlink(cur);
+ if (type(cur) == glyph_node && type(fwd) == glyph_node &&
+ font(cur) == font(fwd) && try_ligature(&cur, fwd))
+ continue;
+ cur = vlink(cur);
+ assert(vlink(alink(cur)) == cur);
+ }
+ tlink(root) = cur;
+ return root;
}
-static halfword
-handle_lig_word(halfword cur) {
- halfword right=null;
-
- if (type(cur)==whatsit_node && subtype(cur)==cancel_boundary_node) {
- halfword prev= alink(cur);
- halfword fwd = vlink(cur);
-/* uncouple_node(cur); */ /* not needed, it is freed */
- flush_node(cur);
- if (fwd==null) {
- vlink(prev) = fwd;
- return prev;
- }
- couple_nodes(prev,fwd);
- if (type(fwd)!=glyph_node) return prev;
- cur = fwd;
- } else if (has_left_boundary(font(cur))) {
- halfword prev= alink(cur);
- halfword p = new_glyph(font(cur),left_boundarychar);
- couple_nodes(prev,p);
- couple_nodes(p,cur);
- cur = p;
- }
- if (has_right_boundary(font(cur))) {
- right = new_glyph(font(cur),right_boundarychar);
- }
-
- while (1) {
- /* A glyph followed by ... */
- if (type(cur)==glyph_node) {
- halfword fwd = vlink(cur);
- if (fwd==null) { /* last character of paragraph */
- if (right==null) break;
- couple_nodes(cur,right);
- right = null;
- continue;
- }
- assert(alink(fwd)==cur);
- if (type(fwd)==glyph_node) { /* GLYPH - 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} */
- halfword pre = vlink_pre_break(fwd);
- halfword nob = vlink_no_break(fwd);
- halfword next, tail;
- liginfo lig;
- assert_disc(fwd);
- /* 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 */
- halfword prev = alink(cur);
- assert(vlink(prev)==cur);
- uncouple_node(cur);
- couple_nodes(prev,fwd);
- nesting_prepend(no_break(fwd),cur);
- /* now ligature the pre_break */
- nesting_prepend(pre_break(fwd),copy_node(cur));
- /* As we have removed cur, we need to start again ... */
- cur = prev;
- }
- /* 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 */
- halfword prev = alink(cur);
- assert(alink(next)==fwd);
- assert(vlink(prev)==cur);
- uncouple_node(cur);
- couple_nodes(prev,fwd);
- couple_nodes(no_break(fwd),cur); /* we _know_ it's empty */
- /* now copy cur the pre_break */
- nesting_prepend(pre_break(fwd),copy_node(cur));
- /* 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 _know_ this works */
- tlink(no_break(fwd)) = next; /* and make sure the list is correct */
- /* 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 ... */
- cur = prev;
- }
- /* we are finished with the pre_break */
- handle_lig_nest(pre_break(fwd),vlink_pre_break(fwd));
- } else if (type(fwd)==whatsit_node && subtype(fwd)==cancel_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 */
- /* right = null; */ /* no need, we're going to leave the loop anyway */
+static halfword handle_lig_word(halfword cur)
+{
+ halfword right = null;
+
+ if (type(cur) == whatsit_node && subtype(cur) == cancel_boundary_node) {
+ halfword prev = alink(cur);
+ halfword fwd = vlink(cur);
+ /* uncouple_node(cur); *//* not needed, it is freed */
+ flush_node(cur);
+ if (fwd == null) {
+ vlink(prev) = fwd;
+ return prev;
}
- break;
- } else { /* fwd is something unknown */
- if (right==null) break;
- couple_nodes(cur,right);
- couple_nodes(right,fwd);
- right = null;
- continue;
- }
- /* A discretionary followed by ... */
- } else if (type(cur)==disc_node) {
- assert_disc(cur);
- /* If {?}{x}{?} or {?}{?}{y} then ... */
- if (vlink_no_break(cur)!=null || vlink_post_break(cur)!=null) {
- halfword fwd;
- halfword lists[511]; /* max 8 levels */
-
- int i, max_depth=0;
- lists[max_depth++] = handle_lig_nest(post_break(cur),vlink_post_break(cur));
- lists[max_depth++] = handle_lig_nest(no_break(cur),vlink_no_break(cur));
- while (1) {
- if ((fwd = vlink(cur))==null) return cur;
- if ( type(fwd)==glyph_node) {
- halfword next;
- for (i=0; i<max_depth; i++) {
- liginfo lig;
- halfword tail = tlink(lists[i]);
- if ( tail!=null && test_ligature(&lig,tail,fwd))
- goto add_glyph_to_all;
+ couple_nodes(prev, fwd);
+ if (type(fwd) != glyph_node)
+ return prev;
+ cur = fwd;
+ } else if (has_left_boundary(font(cur))) {
+ halfword prev = alink(cur);
+ halfword p = new_glyph(font(cur), left_boundarychar);
+ couple_nodes(prev, p);
+ couple_nodes(p, cur);
+ cur = p;
+ }
+ if (has_right_boundary(font(cur))) {
+ right = new_glyph(font(cur), right_boundarychar);
+ }
+
+ while (1) {
+ /* A glyph followed by ... */
+ if (type(cur) == glyph_node) {
+ halfword fwd = vlink(cur);
+ if (fwd == null) { /* last character of paragraph */
+ if (right == null)
+ break;
+ /* --\par prohibits use of couple_nodes here */
+ try_couple_nodes(cur, right);
+ right = null;
+ continue;
}
- /* if we get here, nothing had a ligature, so we stop */
- break;
-add_glyph_to_all:
- for (i=0; i<max_depth; i++) {
- halfword copy = copy_node(fwd);
- halfword tail = tlink(lists[i]);
- nesting_append(lists[i],copy);
- if (tail==null) continue; /* first character - never a ligature */
- handle_lig_nest(lists[i],tail);
+ assert(alink(fwd) == cur);
+ if (type(fwd) == glyph_node) { /* GLYPH - 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} */
+ halfword pre = vlink_pre_break(fwd);
+ halfword nob = vlink_no_break(fwd);
+ halfword next, tail;
+ liginfo lig;
+ assert_disc(fwd);
+ /* 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 */
+ halfword prev = alink(cur);
+ assert(vlink(prev) == cur);
+ uncouple_node(cur);
+ couple_nodes(prev, fwd);
+ nesting_prepend(no_break(fwd), cur);
+ /* now ligature the pre_break */
+ nesting_prepend(pre_break(fwd), copy_node(cur));
+ /* As we have removed cur, we need to start again ... */
+ cur = prev;
+ }
+ /* 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 */
+ halfword prev = alink(cur);
+ assert(alink(next) == fwd);
+ assert(vlink(prev) == cur);
+ uncouple_node(cur);
+ couple_nodes(prev, fwd);
+ couple_nodes(no_break(fwd), cur); /* we _know_ it's empty */
+ /* now copy cur the pre_break */
+ nesting_prepend(pre_break(fwd), copy_node(cur));
+ /* 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 _know_ this works */
+ tlink(no_break(fwd)) = next; /* and make sure the list is correct */
+ /* 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 ... */
+ cur = prev;
+ }
+ /* we are finished with the pre_break */
+ handle_lig_nest(pre_break(fwd), vlink_pre_break(fwd));
+ } else if (type(fwd) == whatsit_node
+ && subtype(fwd) == cancel_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 */
+ /* right = null; *//* no need, we're going to leave the loop anyway */
+ }
+ break;
+ } else { /* fwd is something unknown */
+ if (right == null)
+ break;
+ couple_nodes(cur, right);
+ couple_nodes(right, fwd);
+ right = null;
+ continue;
}
- next = vlink(fwd);
- uncouple_node(fwd);
- try_couple_nodes(cur,next);
- flush_node(fwd);
- } else if ( type(fwd)==disc_node) {
- halfword next;
- /* MAGIC WARNING
- * A disc followed by a disc can have different kernings
- * depending on which path is choosen, and it is impossible to
- * store the possible kernings: fe {}{A}{W} {V}{}{A}
- * So we _always_ add discs so only a simple path remains. */
- int m=max_depth; /* as max_depth changes in this loop */
- for (i=0; i<m; i++) {
- halfword copy = copy_node(fwd);
- halfword tail = tlink(lists[i]);
- if (tail!=null) {
- halfword prev = alink(tail);
- assert(alink(tail)!=null);
- uncouple_node(tail);
- vlink(prev) = null;
- if (prev==lists[i]) {
- tlink(prev) = null;
- } else {
- tlink(lists[i]) = prev;
+ /* A discretionary followed by ... */
+ } else if (type(cur) == disc_node) {
+ assert_disc(cur);
+ /* If {?}{x}{?} or {?}{?}{y} then ... */
+ if (vlink_no_break(cur) != null || vlink_post_break(cur) != null) {
+ halfword fwd;
+ halfword lists[511]; /* max 8 levels */
+
+ int i, max_depth = 0;
+ lists[max_depth++] =
+ handle_lig_nest(post_break(cur), vlink_post_break(cur));
+ lists[max_depth++] =
+ handle_lig_nest(no_break(cur), vlink_no_break(cur));
+ while (1) {
+ if ((fwd = vlink(cur)) == null)
+ return cur;
+ if (type(fwd) == glyph_node) {
+ halfword next;
+ for (i = 0; i < max_depth; i++) {
+ liginfo lig;
+ halfword tail = tlink(lists[i]);
+ if (tail != null && test_ligature(&lig, tail, fwd))
+ goto add_glyph_to_all;
+ }
+ /* if we get here, nothing had a ligature, so we stop */
+ break;
+ add_glyph_to_all:
+ for (i = 0; i < max_depth; i++) {
+ halfword copy = copy_node(fwd);
+ halfword tail = tlink(lists[i]);
+ nesting_append(lists[i], copy);
+ if (tail == null)
+ continue; /* first character - never a ligature */
+ handle_lig_nest(lists[i], tail);
+ }
+ next = vlink(fwd);
+ uncouple_node(fwd);
+ try_couple_nodes(cur, next);
+ flush_node(fwd);
+ } else if (type(fwd) == disc_node) {
+ halfword next;
+ /* MAGIC WARNING
+ * A disc followed by a disc can have different kernings
+ * depending on which path is choosen, and it is impossible to
+ * store the possible kernings: fe {}{A}{W} {V}{}{A}
+ * So we _always_ add discs so only a simple path remains. */
+ int m = max_depth; /* as max_depth changes in this loop */
+ for (i = 0; i < m; i++) {
+ halfword copy = copy_node(fwd);
+ halfword tail = tlink(lists[i]);
+ if (tail != null) {
+ halfword prev = alink(tail);
+ assert(alink(tail) != null);
+ uncouple_node(tail);
+ vlink(prev) = null;
+ if (prev == lists[i]) {
+ tlink(prev) = null;
+ } else {
+ tlink(lists[i]) = prev;
+ }
+ nesting_prepend(pre_break(copy), tail);
+ nesting_prepend(no_break(copy),
+ copy_node(tail));
+ }
+ nesting_append(lists[i], copy);
+ handle_lig_nest(pre_break(copy),
+ vlink_pre_break(copy));
+ assert(max_depth < 256);
+ lists[max_depth++] =
+ handle_lig_nest(no_break(copy),
+ vlink_no_break(copy));
+ lists[i] =
+ handle_lig_nest(post_break(copy),
+ vlink_post_break(copy));
+ }
+ next = vlink(fwd);
+ uncouple_node(fwd);
+ try_couple_nodes(cur, next);
+ flush_node(fwd);
+ } else {
+ return cur;
+ }
}
- nesting_prepend(pre_break(copy),tail);
- nesting_prepend(no_break(copy),copy_node(tail));
- }
- nesting_append(lists[i],copy);
- handle_lig_nest(pre_break(copy),vlink_pre_break(copy));
- assert(max_depth<256);
- lists[max_depth++] = handle_lig_nest(no_break(copy),vlink_no_break(copy));
- lists[i] = handle_lig_nest(post_break(copy),vlink_post_break(copy));
}
- next = vlink(fwd);
- uncouple_node(fwd);
- try_couple_nodes(cur,next);
- flush_node(fwd);
- } else {
+ } else { /* NO GLYPH NOR DISC */
+ /* fprintf(stdout,"This is a %d node\n",type(cur)); */
+ /* assert(0); *//* TODO howcome there can be a glue here? */
return cur;
- }
}
- }
- } else { /* NO GLYPH NOR DISC */
- /* fprintf(stdout,"This is a %d node\n",type(cur));*/
- /* assert(0);*/ /* TODO howcome there can be a glue here? */
- return cur;
- }
- /* step-to-next-node */
- {
- halfword prev = cur;
- cur = vlink(cur);
- assert(cur!=null);
- assert(alink(cur)==prev);
- /* alink(cur) = prev;*/
- }
- }
-
- return cur;
+ /* step-to-next-node */
+ {
+ halfword prev = cur;
+ /* --\par allows vlink(cur) to be null */
+ cur = vlink(cur);
+ if (cur != null) {
+ assert(alink(cur) == prev);
+ }
+ }
+ }
+
+ return cur;
}
/* return = new tail, head should be a dummy */
-halfword
-handle_ligaturing(halfword head, halfword tail) {
- halfword save_tail ; /* trick to allow explicit node==null tests */
- halfword cur, prev;
+halfword handle_ligaturing(halfword head, halfword tail)
+{
+ halfword save_tail; /* trick to allow explicit node==null tests */
+ halfword cur, prev;
- if (vlink(head)==null)
- return tail;
- save_tail = 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)==whatsit_node && subtype(cur)==cancel_boundary_node)) {
- cur = handle_lig_word(cur);
- }
- prev = cur;
- cur = vlink(cur);
- assert(cur==null||alink(cur) == prev);
- }
- if (valid_node(save_tail)) {
- try_couple_nodes(prev,save_tail);
- }
- return prev;
+ if (vlink(head) == null)
+ return tail;
+ save_tail = 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) == whatsit_node
+ && subtype(cur) == cancel_boundary_node)) {
+ cur = handle_lig_word(cur);
+ }
+ prev = cur;
+ cur = vlink(cur);
+ assert(cur == null || alink(cur) == prev);
+ }
+ if (prev == null)
+ prev = tail;
+
+ if (valid_node(save_tail)) {
+ try_couple_nodes(prev, save_tail);
+ }
+ return prev;
}
@@ -1547,124 +1964,128 @@ handle_ligaturing(halfword head, halfword tail) {
*
* ==================================================================== */
-static void
-add_kern_before(halfword left, halfword right) {
- if ((!is_rightghost(right)) &&
- font(left)==font(right) &&
- has_kern(font(left),character(left))) {
- int k = get_kern(font(left),character(left),character(right));
- if (k!=0) {
- halfword kern = new_kern(k);
- halfword prev = alink(right);
- assert(vlink(prev)==right);
- couple_nodes(prev,kern);
- couple_nodes(kern,right);
- }
- }
+static void add_kern_before(halfword left, halfword right)
+{
+ if ((!is_rightghost(right)) &&
+ font(left) == font(right) && has_kern(font(left), character(left))) {
+ int k = raw_get_kern(font(left), character(left), character(right));
+ if (k != 0) {
+ halfword kern = new_kern(k);
+ halfword prev = alink(right);
+ assert(vlink(prev) == right);
+ couple_nodes(prev, kern);
+ couple_nodes(kern, right);
+ }
+ }
}
-static void
-add_kern_after(halfword left, halfword right, halfword aft) {
- if ((!is_rightghost(right)) &&
- font(left)==font(right) &&
- has_kern(font(left),character(left))) {
- int k = get_kern(font(left),character(left),character(right));
- if (k!=0) {
- halfword kern = new_kern(k);
- halfword next = vlink(aft);
- assert(next==null||alink(next)==aft);
- couple_nodes(aft,kern);
- try_couple_nodes(kern,next);
- }
- }
+static void add_kern_after(halfword left, halfword right, halfword aft)
+{
+ if ((!is_rightghost(right)) &&
+ font(left) == font(right) && has_kern(font(left), character(left))) {
+ int k = raw_get_kern(font(left), character(left), character(right));
+ if (k != 0) {
+ halfword kern = new_kern(k);
+ halfword next = vlink(aft);
+ assert(next == null || alink(next) == aft);
+ couple_nodes(aft, kern);
+ try_couple_nodes(kern, next);
+ }
+ }
}
static void
-do_handle_kerning (halfword root, halfword init_left, halfword init_right) {
- halfword cur = vlink(root);
- halfword left = null;
- assert(init_left==null || type(init_left)==glyph_node);
- assert(init_right==null || type(init_right)==glyph_node);
- if (cur==null) {
- if (init_left!=null && init_right!=null) {
- add_kern_after(init_left,init_right,root);
- tlink(root)=vlink(root);
+do_handle_kerning(halfword root, halfword init_left, halfword init_right)
+{
+ halfword cur = vlink(root);
+ halfword left = null;
+ assert(init_left == null || type(init_left) == glyph_node);
+ assert(init_right == null || type(init_right) == glyph_node);
+ if (cur == null) {
+ if (init_left != null && init_right != null) {
+ add_kern_after(init_left, init_right, root);
+ tlink(root) = vlink(root);
+ }
+ return;
}
- return;
- }
- if (type(cur)==glyph_node) {
- set_is_glyph(cur);
- if (init_left!=null)
- add_kern_before(init_left,cur);
- left = cur;
- }
- while ((cur=vlink(cur))!=null) {
- if (type(cur)==glyph_node) {
- set_is_glyph(cur);
- if (left != null) {
- add_kern_before(left,cur);
- if (character(left)<0 || is_ghost(left)) {
- halfword prev = alink(left);
- couple_nodes(prev,cur);
- flush_node(left);
+ if (type(cur) == glyph_node) {
+ set_is_glyph(cur);
+ if (init_left != null)
+ add_kern_before(init_left, cur);
+ left = cur;
+ }
+ while ((cur = vlink(cur)) != null) {
+ if (type(cur) == glyph_node) {
+ set_is_glyph(cur);
+ if (left != null) {
+ add_kern_before(left, cur);
+ if (character(left) < 0 || is_ghost(left)) {
+ halfword prev = alink(left);
+ couple_nodes(prev, cur);
+ flush_node(left);
+ }
+ }
+ left = cur;
+ } else {
+ if (type(cur) == disc_node) {
+ halfword right =
+ type(vlink(cur)) == glyph_node ? vlink(cur) : null;
+ do_handle_kerning(pre_break(cur), left, null);
+ do_handle_kerning(post_break(cur), null, right);
+ if (vlink_post_break(cur) != null)
+ 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? */
+ }
+ if (left != null) {
+ if (character(left) < 0 || is_ghost(left)) {
+ halfword prev = alink(left);
+ couple_nodes(prev, cur);
+ flush_node(left);
+ }
+ left = null;
+ }
}
- }
- left = cur;
- } else {
- if (type(cur)==disc_node) {
- halfword right= type(vlink(cur))==glyph_node ? vlink(cur) : null;
- do_handle_kerning(pre_break(cur),left,null);
- do_handle_kerning(post_break(cur),null,right);
- do_handle_kerning(no_break(cur),left,right);
- }
- if (left != null) {
- if (character(left)<0 || is_ghost(left)) {
- halfword prev = alink(left);
- couple_nodes(prev,cur);
- flush_node(left);
+ }
+ if (left != null) {
+ if (init_right != null)
+ add_kern_after(left, init_right, left);
+ if (character(left) < 0 || is_ghost(left)) {
+ halfword prev = alink(left);
+ halfword next = vlink(left);
+ if (next != null) {
+ couple_nodes(prev, next);
+ tlink(root) = next;
+ assert(vlink(next) == null);
+ assert(type(next) == kern_node);
+ } else if (prev != root) {
+ vlink(prev) = null;
+ tlink(root) = prev;
+ } else {
+ vlink(root) = null;
+ tlink(root) = null;
+ }
+ flush_node(left);
}
- left = null;
- }
- }
- }
- if (left!=null) {
- if (init_right!=null)
- add_kern_after(left,init_right,left);
- if (character(left)<0 || is_ghost(left)) {
- halfword prev = alink(left);
- halfword next = vlink(left);
- if (next!=null) {
- couple_nodes(prev,next);
- tlink(root) = next;
- assert(vlink(next)==null);
- assert(type(next)==kern_node);
- } else if (prev!=root) {
- vlink(prev) = null;
- tlink(root) = prev;
- } else {
- vlink(root) = null;
- tlink(root) = null;
- }
- flush_node(left);
- }
- }
+ }
}
-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;
+ 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;
}
/* ====================================================================
@@ -1674,63 +2095,63 @@ handle_kerning (halfword head, halfword tail) {
* ==================================================================== */
static halfword
-run_lua_ligkern_callback (halfword head, halfword tail, int callback_id){
- lua_State *L = Luas[0];
- lua_rawgeti(L,LUA_REGISTRYINDEX,callback_callbacks_id);
- lua_rawgeti(L,-1, callback_id);
- if (!lua_isfunction(L,-1)) {
- lua_pop(L,2);
- return tail;
- }
- nodelist_to_lua(L,head);
- nodelist_to_lua(L,tail);
- if (lua_pcall(L,2,1,0) != 0) {
- fprintf(stdout,"error: %s\n",lua_tostring(L,-1));
- lua_pop(L,2);
- lua_error(L);
+run_lua_ligkern_callback(halfword head, halfword tail, int callback_id)
+{
+ lua_State *L = Luas;
+ if (!get_callback(L, callback_id)) {
+ lua_pop(L, 2);
+ return tail;
+ }
+ nodelist_to_lua(L, head);
+ nodelist_to_lua(L, tail);
+ if (lua_pcall(L, 2, 1, 0) != 0) {
+ fprintf(stdout, "error: %s\n", lua_tostring(L, -1));
+ lua_pop(L, 2);
+ lua_error(L);
+ return tail;
+ }
+ tail = nodelist_from_lua(L);
+ if (fix_node_lists)
+ fix_node_list(head);
+ lua_pop(L, 2);
return tail;
- }
- tail = nodelist_from_lua(L);
- if (fix_node_lists)
- fix_node_list(head);
- lua_pop(L,2);
- return tail;
}
-halfword
-new_ligkern(halfword head, halfword tail) {
- int callback_id = 0;
+halfword new_ligkern(halfword head, halfword tail)
+{
+ int callback_id = 0;
- assert(head!=null);
- if (vlink(head)==null)
- return tail;
+ assert(head != null);
+ if (vlink(head) == null)
+ return tail;
- callback_id = callback_defined(ligaturing_callback);
- if (callback_id>0) {
- tail = run_lua_ligkern_callback(head,tail,callback_id);
- if (tail==null) tail = tail_of_list(head);
- } else {
- tail = handle_ligaturing(head,tail);
- }
-
- callback_id = callback_defined(kerning_callback);
- if (callback_id>0) {
- tail = run_lua_ligkern_callback(head,tail,callback_id);
- if (tail==null) tail = tail_of_list(head);
- } else {
- halfword nest = new_node(nesting_node,1);
- halfword cur = vlink(head);
- halfword aft = vlink(tail);
- couple_nodes(nest,cur);
- tlink(nest)=tail;
- vlink(tail)=null;
- do_handle_kerning(nest,null,null);
- couple_nodes(head,vlink(nest));
- tail = tlink(nest);
- try_couple_nodes(tail,aft);
- flush_node(nest);
- }
- return tail;
-}
+ callback_id = callback_defined(ligaturing_callback);
+ if (callback_id > 0) {
+ tail = run_lua_ligkern_callback(head, tail, callback_id);
+ if (tail == null)
+ tail = tail_of_list(head);
+ } else {
+ tail = handle_ligaturing(head, tail);
+ }
+ callback_id = callback_defined(kerning_callback);
+ if (callback_id > 0) {
+ tail = run_lua_ligkern_callback(head, tail, callback_id);
+ if (tail == null)
+ tail = tail_of_list(head);
+ } else {
+ halfword nest = new_node(nesting_node, 1);
+ halfword cur = vlink(head);
+ halfword aft = vlink(tail);
+ couple_nodes(nest, cur);
+ tlink(nest) = tail;
+ vlink(tail) = null;
+ do_handle_kerning(nest, null, null);
+ couple_nodes(head, vlink(nest));
+ tail = tlink(nest);
+ try_couple_nodes(tail, aft);
+ flush_node(nest);
+ }
+ return tail;
+}