3 Copyright 2007-2010 Taco Hoekwater <taco@luatex.org>
5 This file is part of LuaTeX.
7 LuaTeX is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2 of the License, or (at your
10 option) any later version.
12 LuaTeX is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License along
18 with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
21 * @desc Support interface for fontforge 20070607
23 * @author Taco Hoekwater
28 #include "lib/lib.h" /* web2c's lib, for recorder_record_input */
30 #include "ffdummies.h"
31 #include "splinefont.h"
33 #define FONT_METATABLE "fontloader.splinefont"
34 #define FONT_SUBFONT_METATABLE "fontloader.splinefont.subfont"
35 #define FONT_GLYPHS_METATABLE "fontloader.splinefont.glyphs"
36 #define FONT_GLYPH_METATABLE "fontloader.splinefont.glyph"
38 #define LUA_OTF_VERSION "0.4"
40 static const char *possub_type_enum
[] = {
41 "null", "position", "pair", "substitution",
42 "alternate", "multiple", "ligature", "lcaret",
43 "kerning", "vkerning", "anchors", "contextpos",
44 "contextsub", "chainpos", "chainsub", "reversesub",
45 "max", "kernback", "vkernback", NULL
48 #define LAST_POSSUB_TYPE_ENUM 18
50 #define eight_nulls() NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
52 static const char *otf_lookup_type_enum
[] = {
53 "gsub_start", "gsub_single", "gsub_multiple", "gsub_alternate",
54 "gsub_ligature", "gsub_context", "gsub_contextchain", NULL
,
55 "gsub_reversecontextchain", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, /*0x00F */
56 eight_nulls(), eight_nulls(),
57 eight_nulls(), eight_nulls(),
58 eight_nulls(), eight_nulls(),
59 eight_nulls(), eight_nulls(),
60 eight_nulls(), eight_nulls(),
61 eight_nulls(), eight_nulls(),
62 eight_nulls(), eight_nulls(),
63 eight_nulls(), eight_nulls(),
64 eight_nulls(), eight_nulls(),
65 eight_nulls(), eight_nulls(),
66 eight_nulls(), eight_nulls(),
67 eight_nulls(), eight_nulls(),
68 eight_nulls(), eight_nulls(),
69 eight_nulls(), eight_nulls(),
70 eight_nulls(), eight_nulls(),
71 "gpos_start", "gpos_single", "gpos_pair", "gpos_cursive",
72 "gpos_mark2base", "gpos_mark2ligature", "gpos_mark2mark", "gpos_context",
73 "gpos_contextchain", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, /* 0x10F */
74 eight_nulls(), eight_nulls(),
75 eight_nulls(), eight_nulls(),
76 eight_nulls(), eight_nulls(),
77 eight_nulls(), eight_nulls(),
78 eight_nulls(), eight_nulls(),
79 eight_nulls(), eight_nulls(),
80 eight_nulls(), eight_nulls(),
81 eight_nulls(), eight_nulls(),
82 eight_nulls(), eight_nulls(),
83 eight_nulls(), eight_nulls(),
84 eight_nulls(), eight_nulls(),
85 eight_nulls(), eight_nulls(),
86 eight_nulls(), eight_nulls(),
87 eight_nulls(), eight_nulls(),
88 eight_nulls(), eight_nulls(),
91 static const char *anchor_type_enum
[] = {
92 "mark", "basechar", "baselig", "basemark", "centry", "cexit", "max", NULL
95 #define MAX_ANCHOR_TYPE 7
97 static const char *anchorclass_type_enum
[] = {
98 "mark", "mkmk", "curs", "mklg", NULL
101 static const char *glyph_class_enum
[] = {
102 "automatic", "none", "base", "ligature", "mark", "component", NULL
105 static const char *ttfnames_enum
[ttf_namemax
] = {
106 "copyright", "family", "subfamily", "uniqueid",
107 "fullname", "version", "postscriptname", "trademark",
108 "manufacturer", "designer", "descriptor", "venderurl",
109 "designerurl", "license", "licenseurl", "idontknow",
110 "preffamilyname", "prefmodifiers", "compatfull", "sampletext",
111 "cidfindfontname", "wwsfamily", "wwssubfamily"
114 static const char *fpossub_format_enum
[] = {
115 "glyphs", "class", "coverage", "reversecoverage", NULL
118 static const char *tex_type_enum
[4] = { "unset", "text", "math", "mathext" };
120 /* has an offset of 1, ui_none = 0. */
121 static const char *uni_interp_enum
[9] = {
122 "unset", "none", "adobe", "greek", "japanese",
123 "trad_chinese", "simp_chinese", "korean", "ams"
126 #define check_isfont(L,b) (SplineFont **)luaL_checkudata(L,b,FONT_METATABLE)
127 #define check_isglyph(L,b) (struct splinechar **)luaL_checkudata(L,b,FONT_GLYPH_METATABLE)
129 /* forward declarations */
130 static void handle_generic_pst(lua_State
* L
, struct generic_pst
*pst
);
131 static void handle_generic_fpst(lua_State
* L
, struct generic_fpst
*fpst
);
132 static void handle_kernclass(lua_State
* L
, struct kernclass
*kerns
, const char *name
);
133 static void handle_splinefont(lua_State
* L
, struct splinefont
*sf
);
134 static void handle_kernpair(lua_State
* L
, struct kernpair
*kp
);
135 static void handle_liglist(lua_State
* L
, struct liglist
*ligofme
);
136 static void handle_anchorpoint(lua_State
* L
, struct anchorpoint
*anchor
);
138 static int is_userdata(lua_State
*L
, int b
, const char *utype
)
140 if (lua_type(L
,b
) == LUA_TUSERDATA
) {
141 lua_getmetatable(L
, b
);
142 luaL_getmetatable(L
, utype
);
143 if (lua_compare(L
, -2, -1, LUA_OPEQ
)) {
152 static void lua_ff_pushfont(lua_State
* L
, SplineFont
* sf
)
158 a
= lua_newuserdata(L
, sizeof(SplineFont
*));
160 luaL_getmetatable(L
, FONT_METATABLE
);
161 lua_setmetatable(L
, -2);
166 static void lua_ff_pushsubfont(lua_State
* L
, SplineFont
* sf
)
172 a
= lua_newuserdata(L
, sizeof(SplineFont
*));
174 luaL_getmetatable(L
, FONT_SUBFONT_METATABLE
);
175 lua_setmetatable(L
, -2);
180 static void lua_ff_pushglyph(lua_State
* L
, struct splinechar
*sc
)
182 struct splinechar
**a
;
186 a
= lua_newuserdata(L
, sizeof(struct splinechar
*));
188 luaL_getmetatable(L
, FONT_GLYPH_METATABLE
);
189 lua_setmetatable(L
, -2);
195 static int ff_open(lua_State
* L
)
198 const char *fontname
;
203 int openflags
= 1 + 4;
204 fontname
= luaL_checkstring(L
, 1);
205 /* test fontname for existance */
206 if ((l
= fopen(fontname
, "r"))) {
207 recorder_record_input(fontname
);
211 lua_pushfstring(L
, "font loading failed for %s (read error)\n", fontname
);
214 args
= lua_gettop(L
);
215 if (args
>= 2 && (lua_type(L
, 2) == LUA_TSTRING
)) {
216 len
= strlen(fontname
);
217 if (*(fontname
+ len
) != ')') {
218 /* possibly fails for embedded parens in the font name */
220 snprintf(s
, 511, "%s", fontname
);
222 snprintf(s
, 511, "%s(%s)", fontname
, lua_tolstring(L
, 2, &len
));
226 snprintf(s
, 511, "%s", fontname
);
230 sf
= ReadSplineFont((char *) s
, openflags
);
233 lua_pushfstring(L
, "font loading failed for %s\n", s
);
234 if (gww_error_count
> 0) {
235 for (i
= 0; i
< gww_error_count
; i
++) {
236 lua_pushstring(L
, gww_errors
[i
]);
242 FVAppend(_FontViewCreate(sf
));
243 lua_ff_pushfont(L
, sf
);
244 if (gww_error_count
> 0) {
246 for (i
= 0; i
< gww_error_count
; i
++) {
247 lua_pushstring(L
, gww_errors
[i
]);
248 lua_rawseti(L
, -2, (i
+ 1));
257 lua_pushfstring(L
, "font loading failed: empty string given\n", fontname
);
262 static int ff_close(lua_State
* L
)
265 /*fputs("ff_close called",stderr); */
266 sf
= check_isfont(L
, 1);
268 if ((*sf
)->fv
) { /* condition might be improved */
269 FontViewClose((*sf
)->fv
);
271 EncMapFree((*sf
)->map
);
279 static int notdef_loc(SplineFont
* sf
)
283 for (k
= 0; k
< sf
->glyphcnt
; k
++) {
285 if (strcmp(sf
->glyphs
[k
]->name
, ".notdef") == 0) {
295 static int ff_apply_featurefile(lua_State
* L
)
299 sf
= check_isfont(L
, 1);
300 fname
= xstrdup(luaL_checkstring(L
, 2));
301 SFApplyFeatureFilename(*sf
, fname
);
302 recorder_record_input(fname
);
304 if (gww_error_count
> 0) {
307 for (i
= 0; i
< gww_error_count
; i
++) {
308 lua_pushstring(L
, gww_errors
[i
]);
309 lua_rawseti(L
, -2, (i
+ 1));
318 static int ff_apply_afmfile(lua_State
* L
)
322 sf
= check_isfont(L
, 1);
323 fname
= luaL_checkstring(L
, 2);
324 CheckAfmOfPostscript(*sf
, fname
, (*sf
)->map
);
325 if (gww_error_count
> 0) {
328 for (i
= 0; i
< gww_error_count
; i
++) {
329 lua_pushstring(L
, gww_errors
[i
]);
330 lua_rawseti(L
, -2, (i
+ 1));
339 static void dump_intfield(lua_State
* L
, const char *name
, long int field
)
341 lua_checkstack(L
, 2);
342 lua_pushstring(L
, name
);
343 lua_pushnumber(L
, field
);
347 static void dump_uintfield(lua_State
* L
, const char *name
, unsigned int field
)
349 lua_checkstack(L
, 2);
350 lua_pushstring(L
, name
);
351 lua_pushnumber(L
, field
);
355 static void dump_realfield(lua_State
* L
, const char *name
, real field
)
357 lua_checkstack(L
, 2);
358 lua_pushstring(L
, name
);
359 lua_pushnumber(L
, field
);
363 #define dump_cond_intfield(a,b,c) if ((c)!=0) { dump_intfield ((a),(b),(c)); }
365 static void dump_stringfield(lua_State
* L
, const char *name
, const char *field
)
367 lua_checkstack(L
, 2);
368 lua_pushstring(L
, name
);
369 lua_pushstring(L
, field
);
373 static void dump_char_ref(lua_State
* L
, struct splinechar
*spchar
)
375 lua_checkstack(L
, 2);
376 lua_pushstring(L
, "char");
377 lua_pushstring(L
, spchar
->name
);
381 static void dump_lstringfield(lua_State
* L
, const char *name
, char *field
, int len
)
383 lua_checkstack(L
, 2);
384 lua_pushstring(L
, name
);
385 lua_pushlstring(L
, field
, len
);
389 static void dump_enumfield(lua_State
* L
, const char *name
, int fid
, const char **fields
)
391 lua_checkstack(L
, 2);
392 lua_pushstring(L
, name
);
393 lua_pushstring(L
, fields
[fid
]);
397 static void dump_floatfield(lua_State
* L
, const char *name
, double field
)
399 lua_checkstack(L
, 2);
400 lua_pushstring(L
, name
);
401 lua_pushnumber(L
, field
);
405 static char tag_string
[5] = { 0 };
407 static char *make_tag_string(unsigned int field
)
409 tag_string
[0] = (field
& 0xFF000000) >> 24;
410 tag_string
[1] = (field
& 0x00FF0000) >> 16;
411 tag_string
[2] = (field
& 0x0000FF00) >> 8;
412 tag_string
[3] = (field
& 0x000000FF);
413 return (char *) tag_string
;
416 static void dump_tag(lua_State
* L
, const char *name
, unsigned int field
)
418 lua_checkstack(L
, 2);
419 lua_pushstring(L
, name
);
420 lua_pushlstring(L
, make_tag_string(field
), 4);
424 static void dump_subtable_name(lua_State
* L
, const char *name
, struct lookup_subtable
*s
)
426 /* this is likely a backref */
429 lua_checkstack(L
, 2);
430 if (s
->next
== NULL
) {
431 dump_stringfield(L
, name
, s
->subtable_name
);
433 /* can this really happen ? */
437 lua_pushstring(L
, s
->subtable_name
);
438 lua_rawseti(L
, -2, ++i
);
441 lua_setfield(L
, -2, name
);
445 #define NESTED_TABLE(a,b,c) { \
448 while (next != NULL) { \
449 lua_checkstack(L,2); \
450 lua_pushnumber(L,k); k++; \
451 lua_createtable(L,0,c); \
458 #define NESTED_TABLE_SF(a,b,c,d) { \
461 while (next != NULL) { \
462 lua_checkstack(L,2); \
463 lua_pushnumber(L,k); k++; \
464 lua_createtable(L,0,d); \
474 static void do_handle_scriptlanglist(lua_State
* L
, struct scriptlanglist
*sl
)
477 dump_tag(L
, "script", sl
->script
);
479 lua_checkstack(L
, 3);
481 for (k
= 0; k
< MAX_LANG
; k
++) {
482 if (sl
->langs
[k
] != 0) {
483 lua_pushnumber(L
, (k
+ 1));
484 lua_pushstring(L
, make_tag_string(sl
->langs
[k
]));
489 if (sl
->lang_cnt
>= MAX_LANG
) {
490 for (k
= MAX_LANG
; k
< sl
->lang_cnt
; k
++) {
491 lua_pushnumber(L
, (k
+ 1));
492 lua_pushstring(L
, make_tag_string(sl
->morelangs
[k
- MAX_LANG
]));
496 lua_setfield(L
, -2, "langs");
499 static void handle_scriptlanglist(lua_State
* L
, struct scriptlanglist
*sll
)
501 struct scriptlanglist
*next
;
502 NESTED_TABLE(do_handle_scriptlanglist
, sll
, 4);
506 do_handle_featurescriptlanglist(lua_State
* L
,
507 struct featurescriptlanglist
*features
)
509 dump_tag(L
, "tag", features
->featuretag
);
511 handle_scriptlanglist(L
, features
->scripts
);
512 lua_setfield(L
, -2, "scripts");
516 handle_featurescriptlanglist(lua_State
* L
,
517 struct featurescriptlanglist
*features
)
519 struct featurescriptlanglist
*next
;
520 NESTED_TABLE(do_handle_featurescriptlanglist
, features
, 3);
523 static void do_handle_lookup_subtable(lua_State
* L
, struct lookup_subtable
*subtable
)
526 dump_stringfield(L
, "name", subtable
->subtable_name
);
527 dump_stringfield(L
, "suffix", subtable
->suffix
);
529 /* struct otlookup *lookup; *//* this is the parent */
531 /* dump_intfield (L,"unused", subtable->unused); */
532 /* The next one is true if there is no fpst, false otherwise */
534 dump_intfield (L,"per_glyph_pst_or_kern",subtable->per_glyph_pst_or_kern);
536 dump_cond_intfield(L
, "anchor_classes", subtable
->anchor_classes
);
537 dump_cond_intfield(L
, "vertical_kerning", subtable
->vertical_kerning
);
539 if (subtable
->kc
!= NULL
) {
541 handle_kernclass(L
, subtable
->kc
, subtable
->subtable_name
);
542 lua_setfield(L
, -2, "kernclass");
545 if (subtable
->fpst
!= NULL
) {
546 /* lua_newtable(L); */
547 handle_generic_fpst(L
, subtable
->fpst
);
548 /* lua_setfield(L,-2, "fpst"); */
552 /* int subtable_offset; *//* used by OTF file generation */
553 /* int32 *extra_subtables; *//* used by OTF file generation */
556 static void handle_lookup_subtable(lua_State
* L
, struct lookup_subtable
*subtable
)
558 struct lookup_subtable
*next
;
559 NESTED_TABLE(do_handle_lookup_subtable
, subtable
, 2);
562 static int do_handle_lookup(lua_State
* L
, struct otlookup
*lookup
, SplineFont
* sf
)
566 dump_enumfield(L
, "type", lookup
->lookup_type
, otf_lookup_type_enum
);
569 if (lookup
->lookup_flags
& pst_r2l
) {
570 lua_pushstring(L
, "r2l");
571 lua_pushboolean(L
, 1);
574 if (lookup
->lookup_flags
& pst_ignorebaseglyphs
) {
575 lua_pushstring(L
, "ignorebaseglyphs");
576 lua_pushboolean(L
, 1);
579 if (lookup
->lookup_flags
& pst_ignoreligatures
) {
580 lua_pushstring(L
, "ignoreligatures");
581 lua_pushboolean(L
, 1);
584 if (lookup
->lookup_flags
& pst_ignorecombiningmarks
) {
585 lua_pushstring(L
, "ignorecombiningmarks");
586 lua_pushboolean(L
, 1);
589 mc
= (lookup
->lookup_flags
>> 8);
590 if (mc
> 0 && mc
< sf
->mark_class_cnt
&& sf
->mark_class_names
[mc
] != NULL
) {
591 lua_pushstring(L
, "mark_class");
592 lua_pushstring(L
, sf
->mark_class_names
[mc
]);
595 lua_setfield(L
, -2, "flags");
599 dump_stringfield(L
, "name", lookup
->lookup_name
);
601 if (lookup
->features
!= NULL
) {
603 handle_featurescriptlanglist(L
, lookup
->features
);
604 lua_setfield(L
, -2, "features");
607 if (lookup
->subtables
!= NULL
) {
609 handle_lookup_subtable(L
, lookup
->subtables
);
610 lua_setfield(L
, -2, "subtables");
613 /* dump_intfield (L,"unused", lookup->unused); */
614 /* dump_intfield (L,"empty", lookup->empty); */
615 /* dump_intfield (L,"store_in_afm", lookup->store_in_afm); */
616 /* dump_intfield (L,"needs_extension", lookup->needs_extension); */
617 /* dump_intfield (L,"temporary_kern", lookup->temporary_kern); */
618 /* dump_intfield (L,"def_lang_checked", lookup->def_lang_checked); */
619 /* dump_intfield (L,"def_lang_found", lookup->def_lang_found); */
620 /* dump_intfield (L,"ticked", lookup->ticked); */
621 /* dump_intfield (L,"subcnt", lookup->subcnt); */
622 /* dump_intfield (L,"lookup_index", lookup->lookup_index); *//* identical to array index */
623 /* dump_intfield (L,"lookup_offset", lookup->lookup_offset); */
624 /* dump_intfield (L,"lookup_length", lookup->lookup_length); */
625 /* dump_stringfield(L,"tempname", lookup->tempname); */
629 static void handle_lookup(lua_State
* L
, struct otlookup
*lookup
, SplineFont
* sf
)
631 struct otlookup
*next
;
632 NESTED_TABLE_SF(do_handle_lookup
, lookup
, sf
, 18); /* 18 is a guess */
635 static void do_handle_kernpair(lua_State
* L
, struct kernpair
*kp
)
639 dump_char_ref(L
, kp
->sc
);
640 dump_intfield(L
, "off", kp
->off
);
641 /* uint16 kcid; *//* temporary value */
642 dump_subtable_name(L
, "lookup", kp
->subtable
);
645 static void handle_kernpair(lua_State
* L
, struct kernpair
*kp
)
647 struct kernpair
*next
;
648 NESTED_TABLE(do_handle_kernpair
, kp
, 4);
651 static void handle_splinecharlist(lua_State
* L
, struct splinecharlist
*scl
)
654 struct splinecharlist
*next
= scl
;
656 lua_checkstack(L
, 10);
657 while (next
!= NULL
) {
658 if (next
->sc
!= NULL
) {
659 lua_pushnumber(L
, k
);
661 lua_pushstring(L
, next
->sc
->name
);
668 /* vs is the "variation selector" a unicode codepoint which modifieds */
669 /* the code point before it. If vs is -1 then unienc is just an */
670 /* alternate encoding (greek Alpha and latin A), but if vs is one */
671 /* of unicode's variation selectors then this glyph is somehow a */
672 /* variant shape. The specifics depend on the selector and script */
673 /* fid is currently unused, but may, someday, be used to do ttcs */
674 /* NOTE: GlyphInfo displays vs==-1 as vs==0, and fixes things up */
676 static int handle_altuni(lua_State
* L
, struct altuni
*au
)
678 struct altuni
*next
= au
;
681 lua_checkstack(L
, 3);
682 while (next
!= NULL
) {
683 if (next
->unienc
<0x10FFFF) {
685 dump_intfield(L
, "unicode", next
->unienc
);
687 if (next
->vs
!= -1) {
688 dump_intfield(L
, "variant", next
->vs
);
689 /* dump_intfield(L, "fid", next->fid); */
691 lua_rawseti(L
, -2, k
++);
693 printf("ignoring variant %i %i\n",next
->unienc
,next
->vs
);
700 #define interesting_vr(a) (((a)->xoff!=0) || ((a)->yoff!=0) || ((a)->h_adv_off!=0) || ((a)->v_adv_off!=0))
702 static void handle_vr(lua_State
* L
, struct vr
*pos
)
705 dump_cond_intfield(L
, "x", pos
->xoff
);
706 dump_cond_intfield(L
, "y", pos
->yoff
);
707 dump_cond_intfield(L
, "h", pos
->h_adv_off
);
708 dump_cond_intfield(L
, "v", pos
->v_adv_off
);
712 static void do_handle_generic_pst(lua_State
* L
, struct generic_pst
*pst
)
715 if (pst
->type
> LAST_POSSUB_TYPE_ENUM
) {
716 dump_tag(L
, "type", pst
->type
);
718 dump_enumfield(L
, "type", pst
->type
, possub_type_enum
);
720 /* unsigned int ticked: 1; */
721 /* unsigned int temporary: 1; *//* Used in afm ligature closure */
722 /* struct lookup_subtable *subtable; *//* handled by caller */
724 lua_checkstack(L
, 4);
725 lua_pushstring(L
, "specification");
726 lua_createtable(L
, 0, 4);
727 if (pst
->type
== pst_position
) {
728 handle_vr(L
, &pst
->u
.pos
);
729 } else if (pst
->type
== pst_pair
) {
730 dump_stringfield(L
, "paired", pst
->u
.pair
.paired
);
731 if (pst
->u
.pair
.vr
!= NULL
) {
732 lua_pushstring(L
, "offsets");
733 lua_createtable(L
, 2, 0);
734 if (interesting_vr(pst
->u
.pair
.vr
)) {
735 lua_createtable(L
, 0, 4);
736 handle_vr(L
, pst
->u
.pair
.vr
);
737 lua_rawseti(L
, -2, 1);
739 if (interesting_vr(pst
->u
.pair
.vr
+ 1)) {
740 lua_createtable(L
, 0, 4);
741 handle_vr(L
, pst
->u
.pair
.vr
+ 1);
742 lua_rawseti(L
, -2, 2);
746 } else if (pst
->type
== pst_substitution
) {
747 dump_stringfield(L
, "variant", pst
->u
.subs
.variant
);
748 } else if (pst
->type
== pst_alternate
) {
749 dump_stringfield(L
, "components", pst
->u
.mult
.components
);
750 } else if (pst
->type
== pst_multiple
) {
751 dump_stringfield(L
, "components", pst
->u
.alt
.components
);
752 } else if (pst
->type
== pst_ligature
) {
753 dump_stringfield(L
, "components", pst
->u
.lig
.components
);
754 if (pst
->u
.lig
.lig
!= NULL
) {
755 dump_char_ref(L
, pst
->u
.lig
.lig
);
757 } else if (pst
->type
== pst_lcaret
) {
758 for (k
= 0; k
< pst
->u
.lcaret
.cnt
; k
++) {
759 lua_pushnumber(L
, (k
+ 1));
760 lua_pushnumber(L
, pst
->u
.lcaret
.carets
[k
]);
767 static void handle_generic_pst(lua_State
* L
, struct generic_pst
*pst
)
769 struct generic_pst
*next
;
773 /* most likely everything arrives in proper order. But to prevent
774 * surprises, better do this is the proper way
776 while (next
!= NULL
) {
777 if (next
->subtable
!= NULL
&& next
->subtable
->subtable_name
!= NULL
) {
778 lua_checkstack(L
, 3); /* just in case */
779 lua_getfield(L
, -1, next
->subtable
->subtable_name
);
780 if (!lua_istable(L
, -1)) {
783 lua_setfield(L
, -2, next
->subtable
->subtable_name
);
784 lua_getfield(L
, -1, next
->subtable
->subtable_name
);
786 k
= lua_rawlen(L
, -1) + 1;
787 lua_pushnumber(L
, k
);
788 lua_createtable(L
, 0, 4);
789 do_handle_generic_pst(L
, next
);
792 lua_pop(L
, 1); /* pop the subtable */
794 /* Found a pst without subtable, or without subtable name */
795 lua_pushnumber(L
, l
);
797 lua_createtable(L
, 0, 4);
798 do_handle_generic_pst(L
, next
);
805 static void do_handle_liglist(lua_State
* L
, struct liglist
*ligofme
)
807 lua_checkstack(L
, 2);
808 if (ligofme
->lig
!= NULL
) {
809 lua_createtable(L
, 0, 6);
810 handle_generic_pst(L
, ligofme
->lig
);
811 lua_setfield(L
, -2, "lig");
813 dump_char_ref(L
, ligofme
->first
);
814 if (ligofme
->components
!= NULL
) {
816 handle_splinecharlist(L
, ligofme
->components
);
817 lua_setfield(L
, -2, "components");
819 dump_intfield(L
, "ccnt", ligofme
->ccnt
);
823 static void handle_liglist(lua_State
* L
, struct liglist
*ligofme
)
825 struct liglist
*next
;
826 NESTED_TABLE(do_handle_liglist
, ligofme
, 3);
829 static void do_handle_anchorpoint(lua_State
* L
, struct anchorpoint
*anchor
)
832 if (anchor
->anchor
== NULL
) {
835 if (anchor
->type
>= 0 && anchor
->type
<= MAX_ANCHOR_TYPE
) {
836 lua_pushstring(L
, anchor_type_enum
[anchor
->type
]);
838 lua_pushstring(L
, "Anchorpoint has an unknown type!");
841 /* unsigned int selected: 1; */
842 /* unsigned int ticked: 1; */
845 if (!lua_istable(L
, -1)) {
846 /* create the table first */
848 lua_pushstring(L
, anchor_type_enum
[anchor
->type
]);
849 lua_pushvalue(L
, -1);
854 /* now the 'type' table is top of stack */
855 if (anchor
->type
== at_baselig
) {
856 lua_pushstring(L
, anchor
->anchor
->name
);
858 if (!lua_istable(L
, -1)) {
859 /* create the table first */
861 lua_pushstring(L
, anchor
->anchor
->name
);
862 lua_pushvalue(L
, -1);
868 dump_intfield(L
, "x", anchor
->me
.x
);
869 dump_intfield(L
, "y", anchor
->me
.y
);
870 if (anchor
->has_ttf_pt
)
871 dump_intfield(L
, "ttf_pt_index", anchor
->ttf_pt_index
);
872 dump_intfield(L
, "lig_index", anchor
->lig_index
);
873 lua_rawseti(L
, -2, (anchor
->lig_index
+ 1));
876 lua_pushstring(L
, anchor
->anchor
->name
);
878 dump_intfield(L
, "x", anchor
->me
.x
);
879 dump_intfield(L
, "y", anchor
->me
.y
);
880 if (anchor
->has_ttf_pt
)
881 dump_intfield(L
, "ttf_pt_index", anchor
->ttf_pt_index
);
882 dump_intfield(L
, "lig_index", anchor
->lig_index
);
888 static void handle_anchorpoint(lua_State
* L
, struct anchorpoint
*anchor
)
890 struct anchorpoint
*next
;
892 while (next
!= NULL
) {
893 do_handle_anchorpoint(L
, next
);
898 static void handle_glyphvariants(lua_State
* L
, struct glyphvariants
*vars
)
901 dump_stringfield(L
, "variants", vars
->variants
);
902 dump_intfield(L
, "italic_correction", vars
->italic_correction
);
904 for (i
= 0; i
< vars
->part_cnt
; i
++) {
906 dump_stringfield(L
, "component", vars
->parts
[i
].component
);
907 dump_intfield(L
, "extender", vars
->parts
[i
].is_extender
);
908 dump_intfield(L
, "start", vars
->parts
[i
].startConnectorLength
);
909 dump_intfield(L
, "end", vars
->parts
[i
].endConnectorLength
);
910 dump_intfield(L
, "advance", vars
->parts
[i
].fullAdvance
);
911 lua_rawseti(L
, -2, (i
+ 1));
913 lua_setfield(L
, -2, "parts");
916 static void handle_mathkernvertex(lua_State
* L
, struct mathkernvertex
*mkv
)
919 for (i
= 0; i
< mkv
->cnt
; i
++) {
921 dump_intfield(L
, "height", mkv
->mkd
[i
].height
);
922 dump_intfield(L
, "kern", mkv
->mkd
[i
].kern
);
923 lua_rawseti(L
, -2, (i
+ 1));
927 static void handle_mathkern(lua_State
* L
, struct mathkern
*mk
)
930 handle_mathkernvertex(L
, &(mk
->top_right
));
931 lua_setfield(L
, -2, "top_right");
933 handle_mathkernvertex(L
, &(mk
->top_left
));
934 lua_setfield(L
, -2, "top_left");
936 handle_mathkernvertex(L
, &(mk
->bottom_right
));
937 lua_setfield(L
, -2, "bottom_right");
939 handle_mathkernvertex(L
, &(mk
->bottom_left
));
940 lua_setfield(L
, -2, "bottom_left");
943 static void handle_splinechar(lua_State
* L
, struct splinechar
*glyph
, int hasvmetrics
)
946 if (glyph
->xmax
== 0 && glyph
->ymax
== 0 && glyph
->xmin
== 0
947 && glyph
->ymin
== 0) {
948 SplineCharFindBounds(glyph
, &bb
);
949 glyph
->xmin
= bb
.minx
;
950 glyph
->ymin
= bb
.miny
;
951 glyph
->xmax
= bb
.maxx
;
952 glyph
->ymax
= bb
.maxy
;
954 dump_stringfield(L
, "name", glyph
->name
);
955 dump_intfield(L
, "unicode", glyph
->unicodeenc
);
956 lua_createtable(L
, 4, 0);
957 lua_pushnumber(L
, 1);
958 lua_pushnumber(L
, glyph
->xmin
);
960 lua_pushnumber(L
, 2);
961 lua_pushnumber(L
, glyph
->ymin
);
963 lua_pushnumber(L
, 3);
964 lua_pushnumber(L
, glyph
->xmax
);
966 lua_pushnumber(L
, 4);
967 lua_pushnumber(L
, glyph
->ymax
);
969 lua_setfield(L
, -2, "boundingbox");
970 if (glyph
->orig_pos
>=0) {
971 dump_intfield(L
,"orig_pos",glyph
->orig_pos
);
974 dump_intfield(L
, "vwidth", glyph
->vwidth
);
976 dump_intfield(L
, "tsidebearing", glyph
->tsb
);
978 dump_intfield(L
, "width", glyph
->width
);
980 if (glyph
->lsidebearing
!= glyph
->xmin
) {
981 dump_cond_intfield(L
, "lsidebearing", glyph
->lsidebearing
);
983 /* dump_intfield(L,"ttf_glyph", glyph->ttf_glyph); */
985 /* Layer layers[2]; *//* TH Not used */
986 /* int layer_cnt; *//* TH Not used */
987 /* StemInfo *hstem; *//* TH Not used */
988 /* StemInfo *vstem; *//* TH Not used */
989 /* DStemInfo *dstem; *//* TH Not used */
991 /* MinimumDistance *md; *//* TH Not used */
992 /* struct charviewbase *views; *//* TH Not used */
993 /* struct charinfo *charinfo; *//* TH ? (charinfo.c) */
994 /* struct splinefont *parent; *//* TH Not used */
996 if (glyph
->glyph_class
> 0) {
997 dump_enumfield(L
, "class", glyph
->glyph_class
, glyph_class_enum
);
999 /* TH: internal fontforge stuff
1000 dump_intfield(L,"changed", glyph->changed);
1001 dump_intfield(L,"changedsincelasthinted", glyph->changedsincelasthinted);
1002 dump_intfield(L,"manualhints", glyph->manualhints);
1003 dump_intfield(L,"ticked", glyph->ticked);
1004 dump_intfield(L,"changed_since_autosave", glyph->changed_since_autosave);
1005 dump_intfield(L,"widthset", glyph->widthset);
1006 dump_intfield(L,"vconflicts", glyph->vconflicts);
1007 dump_intfield(L,"hconflicts", glyph->hconflicts);
1008 dump_intfield(L,"searcherdummy", glyph->searcherdummy);
1009 dump_intfield(L,"changed_since_search", glyph->changed_since_search);
1010 dump_intfield(L,"wasopen", glyph->wasopen);
1011 dump_intfield(L,"namechanged", glyph->namechanged);
1012 dump_intfield(L,"blended", glyph->blended);
1013 dump_intfield(L,"ticked2", glyph->ticked2);
1014 dump_intfield(L,"unused_so_far", glyph->unused_so_far);
1015 dump_intfield(L,"numberpointsbackards", glyph->numberpointsbackards);
1016 dump_intfield(L,"instructions_out_of_date", glyph->instructions_out_of_date);
1017 dump_intfield(L,"complained_about_ptnums", glyph->complained_about_ptnums);
1018 unsigned int vs_open: 1;
1019 unsigned int unlink_rm_ovrlp_save_undo: 1;
1020 unsigned int inspiro: 1;
1021 unsigned int lig_caret_cnt_fixed: 1;
1025 int16 ttf_instrs_len;
1026 int16 countermask_cnt;
1027 HintMask *countermasks;
1030 if (glyph
->kerns
!= NULL
) {
1032 handle_kernpair(L
, glyph
->kerns
);
1033 lua_setfield(L
, -2, "kerns");
1035 if (glyph
->vkerns
!= NULL
) {
1037 handle_kernpair(L
, glyph
->vkerns
);
1038 lua_setfield(L
, -2, "vkerns");
1041 if (glyph
->dependents
!= NULL
) {
1043 handle_splinecharlist(L
, glyph
->dependents
);
1044 lua_setfield(L
, -2, "dependents");
1047 if (glyph
->possub
!= NULL
) {
1049 handle_generic_pst(L
, glyph
->possub
);
1050 lua_setfield(L
, -2, "lookups");
1053 if (glyph
->ligofme
!= NULL
) {
1055 handle_liglist(L
, glyph
->ligofme
);
1056 lua_setfield(L
, -2, "ligatures");
1059 if (glyph
->comment
!= NULL
)
1060 dump_stringfield(L
, "comment", glyph
->comment
);
1062 /* Color color; *//* dont care */
1064 if (glyph
->anchor
!= NULL
) {
1066 handle_anchorpoint(L
, glyph
->anchor
);
1067 lua_setfield(L
, -2, "anchors");
1070 if (glyph
->altuni
!= NULL
) {
1073 i
= handle_altuni(L
, glyph
->altuni
);
1075 lua_setfield(L
, -2, "altuni");
1081 if (glyph
->tex_height
!= TEX_UNDEF
)
1082 dump_intfield(L
, "tex_height", glyph
->tex_height
);
1083 if (glyph
->tex_depth
!= TEX_UNDEF
)
1084 dump_intfield(L
, "tex_depth", glyph
->tex_depth
);
1086 dump_cond_intfield(L
, "is_extended_shape", glyph
->is_extended_shape
);
1087 if (glyph
->italic_correction
!= TEX_UNDEF
)
1088 dump_intfield(L
, "italic_correction", glyph
->italic_correction
);
1089 if (glyph
->top_accent_horiz
!= TEX_UNDEF
)
1090 dump_intfield(L
, "top_accent", glyph
->top_accent_horiz
);
1092 if (glyph
->vert_variants
!= NULL
) {
1094 handle_glyphvariants(L
, glyph
->vert_variants
);
1095 lua_setfield(L
, -2, "vert_variants");
1097 if (glyph
->horiz_variants
!= NULL
) {
1099 handle_glyphvariants(L
, glyph
->horiz_variants
);
1100 lua_setfield(L
, -2, "horiz_variants");
1102 if (glyph
->mathkern
!= NULL
) {
1104 handle_mathkern(L
, glyph
->mathkern
);
1105 lua_setfield(L
, -2, "mathkern");
1109 const char *panose_values_0
[] = {
1110 "Any", "No Fit", "Text and Display", "Script", "Decorative", "Pictorial"
1113 const char *panose_values_1
[] = {
1114 "Any", "No Fit", "Cove", "Obtuse Cove", "Square Cove",
1115 "Obtuse Square Cove",
1116 "Square", "Thin", "Bone", "Exaggerated", "Triangle", "Normal Sans",
1117 "Obtuse Sans", "Perp Sans", "Flared", "Rounded"
1120 const char *panose_values_2
[] = {
1121 "Any", "No Fit", "Very Light", "Light", "Thin", "Book",
1122 "Medium", "Demi", "Bold", "Heavy", "Black", "Nord"
1125 const char *panose_values_3
[] = {
1126 "Any", "No Fit", "Old Style", "Modern", "Even Width",
1127 "Expanded", "Condensed", "Very Expanded", "Very Condensed", "Monospaced"
1130 const char *panose_values_4
[] = {
1131 "Any", "No Fit", "None", "Very Low", "Low", "Medium Low",
1132 "Medium", "Medium High", "High", "Very High"
1135 const char *panose_values_5
[] = {
1136 "Any", "No Fit", "Gradual/Diagonal", "Gradual/Transitional",
1138 "Gradual/Horizontal", "Rapid/Vertical", "Rapid/Horizontal",
1142 const char *panose_values_6
[] = {
1143 "Any", "No Fit", "Straight Arms/Horizontal", "Straight Arms/Wedge",
1144 "Straight Arms/Vertical",
1145 "Straight Arms/Single Serif", "Straight Arms/Double Serif",
1146 "Non-Straight Arms/Horizontal",
1147 "Non-Straight Arms/Wedge", "Non-Straight Arms/Vertical",
1148 "Non-Straight Arms/Single Serif",
1149 "Non-Straight Arms/Double Serif"
1152 const char *panose_values_7
[] = {
1153 "Any", "No Fit", "Normal/Contact", "Normal/Weighted", "Normal/Boxed",
1155 "Normal/Rounded", "Normal/Off Center", "Normal/Square", "Oblique/Contact",
1157 "Oblique/Boxed", "Oblique/Flattened", "Oblique/Rounded",
1158 "Oblique/Off Center", "Oblique/Square"
1161 const char *panose_values_8
[] = {
1162 "Any", "No Fit", "Standard/Trimmed", "Standard/Pointed",
1163 "Standard/Serifed", "High/Trimmed",
1164 "High/Pointed", "High/Serifed", "Constant/Trimmed", "Constant/Pointed",
1166 "Low/Trimmed", "Low/Pointed", "Low/Serifed"
1169 const char *panose_values_9
[] = {
1170 "Any", "No Fit", "Constant/Small", "Constant/Standard",
1171 "Constant/Large", "Ducking/Small", "Ducking/Standard", "Ducking/Large"
1174 #define panose_values_0_max 5
1175 #define panose_values_1_max 15
1176 #define panose_values_2_max 11
1177 #define panose_values_3_max 9
1178 #define panose_values_4_max 9
1179 #define panose_values_5_max 8
1180 #define panose_values_6_max 11
1181 #define panose_values_7_max 15
1182 #define panose_values_8_max 13
1183 #define panose_values_9_max 7
1185 #define fix_range(a,b) (b<0 ? 0 : (b>a ? 0 : b))
1187 static void handle_pfminfo(lua_State
* L
, struct pfminfo pfm
)
1190 dump_intfield(L
, "pfmset", pfm
.pfmset
);
1191 dump_intfield(L
, "winascent_add", pfm
.winascent_add
);
1192 dump_intfield(L
, "windescent_add", pfm
.windescent_add
);
1193 dump_intfield(L
, "hheadascent_add", pfm
.hheadascent_add
);
1194 dump_intfield(L
, "hheaddescent_add", pfm
.hheaddescent_add
);
1195 dump_intfield(L
, "typoascent_add", pfm
.typoascent_add
);
1196 dump_intfield(L
, "typodescent_add", pfm
.typodescent_add
);
1197 dump_intfield(L
, "subsuper_set", pfm
.subsuper_set
);
1198 dump_intfield(L
, "panose_set", pfm
.panose_set
);
1199 dump_intfield(L
, "hheadset", pfm
.hheadset
);
1200 dump_intfield(L
, "vheadset", pfm
.vheadset
);
1201 dump_intfield(L
, "pfmfamily", pfm
.pfmfamily
);
1202 dump_intfield(L
, "weight", pfm
.weight
);
1203 dump_intfield(L
, "width", pfm
.width
);
1204 dump_intfield(L
, "avgwidth", pfm
.avgwidth
);
1205 dump_intfield(L
, "firstchar", pfm
.firstchar
);
1206 dump_intfield(L
, "lastchar", pfm
.lastchar
);
1207 lua_createtable(L
, 0, 10);
1208 dump_enumfield(L
, "familytype",
1209 fix_range(panose_values_0_max
, pfm
.panose
[0]),
1211 dump_enumfield(L
, "serifstyle",
1212 fix_range(panose_values_1_max
, pfm
.panose
[1]),
1214 dump_enumfield(L
, "weight", fix_range(panose_values_2_max
, pfm
.panose
[2]),
1216 dump_enumfield(L
, "proportion",
1217 fix_range(panose_values_3_max
, pfm
.panose
[3]),
1219 dump_enumfield(L
, "contrast", fix_range(panose_values_4_max
, pfm
.panose
[4]),
1221 dump_enumfield(L
, "strokevariation",
1222 fix_range(panose_values_5_max
, pfm
.panose
[5]),
1224 dump_enumfield(L
, "armstyle", fix_range(panose_values_6_max
, pfm
.panose
[6]),
1226 dump_enumfield(L
, "letterform",
1227 fix_range(panose_values_7_max
, pfm
.panose
[7]),
1229 dump_enumfield(L
, "midline", fix_range(panose_values_8_max
, pfm
.panose
[8]),
1231 dump_enumfield(L
, "xheight", fix_range(panose_values_9_max
, pfm
.panose
[9]),
1233 lua_setfield(L
, -2, "panose");
1235 dump_intfield(L
, "fstype", pfm
.fstype
);
1236 dump_intfield(L
, "linegap", pfm
.linegap
);
1237 dump_intfield(L
, "vlinegap", pfm
.vlinegap
);
1238 dump_intfield(L
, "hhead_ascent", pfm
.hhead_ascent
);
1239 dump_intfield(L
, "hhead_descent", pfm
.hhead_descent
);
1240 dump_intfield(L
, "hhead_descent", pfm
.hhead_descent
);
1241 dump_intfield(L
, "os2_typoascent", pfm
.os2_typoascent
);
1242 dump_intfield(L
, "os2_typodescent", pfm
.os2_typodescent
);
1243 dump_intfield(L
, "os2_typolinegap", pfm
.os2_typolinegap
);
1244 dump_intfield(L
, "os2_winascent", pfm
.os2_winascent
);
1245 dump_intfield(L
, "os2_windescent", pfm
.os2_windescent
);
1246 dump_intfield(L
, "os2_subxsize", pfm
.os2_subxsize
);
1247 dump_intfield(L
, "os2_subysize", pfm
.os2_subysize
);
1248 dump_intfield(L
, "os2_subxoff", pfm
.os2_subxoff
);
1249 dump_intfield(L
, "os2_subyoff", pfm
.os2_subyoff
);
1250 dump_intfield(L
, "os2_supxsize", pfm
.os2_supxsize
);
1251 dump_intfield(L
, "os2_supysize", pfm
.os2_supysize
);
1252 dump_intfield(L
, "os2_supxoff", pfm
.os2_supxoff
);
1253 dump_intfield(L
, "os2_supyoff", pfm
.os2_supyoff
);
1254 dump_intfield(L
, "os2_strikeysize", pfm
.os2_strikeysize
);
1255 dump_intfield(L
, "os2_strikeypos", pfm
.os2_strikeypos
);
1256 dump_lstringfield(L
, "os2_vendor", pfm
.os2_vendor
, 4);
1257 dump_intfield(L
, "os2_family_class", pfm
.os2_family_class
);
1258 dump_intfield(L
, "os2_xheight", pfm
.os2_xheight
);
1259 dump_intfield(L
, "os2_capheight", pfm
.os2_capheight
);
1260 dump_intfield(L
, "os2_defaultchar", pfm
.os2_defaultchar
);
1261 dump_intfield(L
, "os2_breakchar", pfm
.os2_breakchar
);
1262 if (pfm
.hascodepages
) {
1264 lua_pushnumber(L
, pfm
.codepages
[0]);
1265 lua_rawseti(L
, -2, 1);
1266 lua_pushnumber(L
, pfm
.codepages
[1]);
1267 lua_rawseti(L
, -2, 2);
1268 lua_setfield(L
, -2, "codepages");
1270 if (pfm
.hasunicoderanges
) {
1272 lua_pushnumber(L
, pfm
.unicoderanges
[0]);
1273 lua_rawseti(L
, -2, 1);
1274 lua_pushnumber(L
, pfm
.unicoderanges
[1]);
1275 lua_rawseti(L
, -2, 2);
1276 lua_pushnumber(L
, pfm
.unicoderanges
[2]);
1277 lua_rawseti(L
, -2, 3);
1278 lua_pushnumber(L
, pfm
.unicoderanges
[3]);
1279 lua_rawseti(L
, -2, 4);
1280 lua_setfield(L
, -2, "unicoderanges");
1285 static char *do_handle_enc(lua_State
* L
, struct enc
*enc
)
1288 char *ret
= enc
->enc_name
;
1289 dump_stringfield(L
, "enc_name", enc
->enc_name
);
1290 dump_intfield(L
, "char_cnt", enc
->char_cnt
);
1292 lua_checkstack(L
, 4);
1293 if (enc
->char_cnt
&& enc
->unicode
!= NULL
) {
1294 lua_createtable(L
, enc
->char_cnt
, 1);
1295 for (i
= 0; i
< enc
->char_cnt
; i
++) {
1296 lua_pushnumber(L
, i
);
1297 lua_pushnumber(L
, enc
->unicode
[i
]);
1300 lua_setfield(L
, -2, "unicode");
1303 if (enc
->char_cnt
&& enc
->psnames
!= NULL
) {
1304 lua_createtable(L
, enc
->char_cnt
, 1);
1305 for (i
= 0; i
< enc
->char_cnt
; i
++) {
1306 lua_pushnumber(L
, i
);
1307 lua_pushstring(L
, enc
->psnames
[i
]);
1310 lua_setfield(L
, -2, "psnames");
1312 dump_intfield(L
, "builtin", enc
->builtin
);
1313 dump_intfield(L
, "hidden", enc
->hidden
);
1314 dump_intfield(L
, "only_1byte", enc
->only_1byte
);
1315 dump_intfield(L
, "has_1byte", enc
->has_1byte
);
1316 dump_intfield(L
, "has_2byte", enc
->has_2byte
);
1317 dump_cond_intfield(L
, "is_unicodebmp", enc
->is_unicodebmp
);
1318 dump_cond_intfield(L
, "is_unicodefull", enc
->is_unicodefull
);
1319 dump_cond_intfield(L
, "is_custom", enc
->is_custom
);
1320 dump_cond_intfield(L
, "is_original", enc
->is_original
);
1321 dump_cond_intfield(L
, "is_compact", enc
->is_compact
);
1322 dump_cond_intfield(L
, "is_japanese", enc
->is_japanese
);
1323 dump_cond_intfield(L
, "is_korean", enc
->is_korean
);
1324 dump_cond_intfield(L
, "is_tradchinese", enc
->is_tradchinese
);
1325 dump_cond_intfield(L
, "is_simplechinese", enc
->is_simplechinese
);
1327 if (enc
->iso_2022_escape_len
> 0) {
1328 dump_lstringfield(L
, "iso_2022_escape", enc
->iso_2022_escape
,
1329 enc
->iso_2022_escape_len
);
1331 dump_intfield(L
, "low_page", enc
->low_page
);
1332 dump_intfield(L
, "high_page", enc
->high_page
);
1334 dump_stringfield(L
, "iconv_name", enc
->iconv_name
);
1336 dump_intfield(L
, "char_max", enc
->char_max
);
1341 static void handle_enc(lua_State
* L
, struct enc
*enc
)
1344 NESTED_TABLE(do_handle_enc
, enc
, 24);
1348 static void handle_encmap(lua_State
* L
, struct encmap
*map
, int notdef_loc
)
1351 dump_intfield(L
, "enccount", map
->enccount
);
1352 dump_intfield(L
, "encmax", map
->encmax
);
1353 dump_intfield(L
, "backmax", map
->backmax
);
1354 /*dump_intfield(L,"ticked", map->ticked) ; */
1355 if (map
->remap
!= NULL
) {
1357 dump_intfield(L
, "firstenc", map
->remap
->firstenc
);
1358 dump_intfield(L
, "lastenc", map
->remap
->lastenc
);
1359 dump_intfield(L
, "infont", map
->remap
->infont
);
1360 lua_setfield(L
, -2, "remap");
1362 lua_checkstack(L
, 4);
1363 if (map
->encmax
> 0 && map
->map
!= NULL
) {
1364 lua_createtable(L
, map
->encmax
, 1);
1365 for (i
= 0; i
< map
->encmax
; i
++) {
1366 if (map
->map
[i
] != -1) {
1367 int l
= map
->map
[i
];
1368 lua_pushnumber(L
, i
);
1370 lua_pushnumber(L
, (l
+ 1));
1372 lua_pushnumber(L
, l
);
1376 lua_setfield(L
, -2, "map");
1379 if (map
->backmax
> 0 && map
->backmap
!= NULL
) {
1381 for (i
= 0; i
< map
->backmax
; i
++) {
1382 if (map
->backmap
[i
] != -1) { /* TODO: check this, because valgrind sometimes says
1383 "Conditional jump or move depends on uninitialised value(s)"
1387 lua_pushnumber(L
, (i
+ 1));
1389 lua_pushnumber(L
, i
);
1390 lua_pushnumber(L
, map
->backmap
[i
]);
1394 lua_setfield(L
, -2, "backmap");
1397 if (map
->enc
!= NULL
) {
1400 encname
= do_handle_enc(L
, map
->enc
);
1401 lua_setfield(L
, -2, "enc");
1402 lua_pushstring(L
, encname
);
1403 lua_setfield(L
, -2, "enc_name");
1407 static void handle_psdict(lua_State
* L
, struct psdict
*private)
1410 if (private->keys
!= NULL
&& private->values
!= NULL
) {
1411 for (k
= 0; k
< private->next
; k
++) {
1412 lua_pushstring(L
, private->keys
[k
]);
1413 lua_pushstring(L
, private->values
[k
]);
1419 static void do_handle_ttflangname(lua_State
* L
, struct ttflangname
*names
)
1422 dump_stringfield(L
, "lang", MSLangString(names
->lang
));
1423 lua_checkstack(L
, 4);
1424 lua_createtable(L
, 0, ttf_namemax
);
1425 for (k
= 0; k
< ttf_namemax
; k
++) {
1426 lua_pushstring(L
, ttfnames_enum
[k
]);
1427 lua_pushstring(L
, names
->names
[k
]);
1430 lua_setfield(L
, -2, "names");
1433 static void handle_ttflangname(lua_State
* L
, struct ttflangname
*names
)
1435 struct ttflangname
*next
;
1436 NESTED_TABLE(do_handle_ttflangname
, names
, 2);
1439 static void do_handle_anchorclass(lua_State
* L
, struct anchorclass
*anchor
)
1442 dump_stringfield(L
, "name", anchor
->name
);
1443 dump_subtable_name(L
, "lookup", anchor
->subtable
);
1444 dump_enumfield(L
, "type", anchor
->type
, anchorclass_type_enum
);
1445 /* uint8 has_base; */
1446 /* uint8 processed, has_mark, matches, ac_num; */
1450 static void handle_anchorclass(lua_State
* L
, struct anchorclass
*anchor
)
1452 struct anchorclass
*next
;
1453 NESTED_TABLE(do_handle_anchorclass
, anchor
, 10);
1456 static void do_handle_ttf_table(lua_State
* L
, struct ttf_table
*ttf_tab
)
1459 dump_tag(L
, "tag", ttf_tab
->tag
);
1460 dump_intfield(L
, "len", ttf_tab
->len
);
1461 dump_intfield(L
, "maxlen", ttf_tab
->maxlen
);
1462 dump_lstringfield(L
, "data", (char *) ttf_tab
->data
, ttf_tab
->len
);
1465 static void handle_ttf_table(lua_State
* L
, struct ttf_table
*ttf_tab
)
1467 struct ttf_table
*next
;
1468 NESTED_TABLE(do_handle_ttf_table
, ttf_tab
, 4);
1471 static int do_handle_kernclass(lua_State
* L
, struct kernclass
*kerns
, const char *name
)
1476 struct lookup_subtable
*s
= kerns
->subtable
;
1478 if (strcmp(s
->subtable_name
,name
)==0) {
1490 lua_checkstack(L
, 4);
1491 lua_createtable(L
, kerns
->first_cnt
, 1);
1492 for (k
= 0; k
< kerns
->first_cnt
; k
++) {
1493 lua_pushnumber(L
, (k
+ 1));
1494 lua_pushstring(L
, kerns
->firsts
[k
]);
1497 lua_setfield(L
, -2, "firsts");
1499 lua_createtable(L
, kerns
->second_cnt
, 1);
1500 for (k
= 0; k
< kerns
->second_cnt
; k
++) {
1501 lua_pushnumber(L
, (k
+ 1));
1502 lua_pushstring(L
, kerns
->seconds
[k
]);
1505 lua_setfield(L
, -2, "seconds");
1508 dump_subtable_name(L
, "lookup", kerns
->subtable
);
1511 lua_createtable(L
, kerns
->second_cnt
* kerns
->first_cnt
, 1);
1512 for (k
= 0; k
< (kerns
->second_cnt
* kerns
->first_cnt
); k
++) {
1513 if (kerns
->offsets
[k
] != 0) {
1514 lua_pushnumber(L
, (k
+ 1));
1515 lua_pushnumber(L
, kerns
->offsets
[k
]);
1519 lua_setfield(L
, -2, "offsets");
1523 static void handle_kernclass(lua_State
* L
, struct kernclass
*kerns
, const char *name
)
1525 struct kernclass
*next
;
1526 NESTED_TABLE_SF(do_handle_kernclass
, kerns
, name
, 8);
1530 #define DUMP_NUMBER_ARRAY(s,cnt,item) { \
1531 if (cnt>0 && item != NULL) { \
1534 for (kk=0;kk<cnt;kk++) { \
1535 lua_pushnumber(L,(kk+1)); \
1536 lua_pushnumber(L,item[kk]); \
1537 lua_rawset(L,-3); } \
1538 lua_setfield(L,-2,s); } }
1541 #define DUMP_STRING_ARRAY(s,cnt,item) { \
1542 if (cnt>0 && item!=NULL) { \
1545 for (kk=0;kk<cnt;kk++) { \
1546 lua_pushnumber(L,(kk+1)); \
1547 lua_pushstring(L,item[kk]); \
1548 lua_rawset(L,-3); } \
1549 lua_setfield(L,-2,s); } }
1551 #define DUMP_EXACT_STRING_ARRAY(s,cnt,item) { \
1552 if (cnt>0 && item!=NULL) { \
1555 for (kk=0;kk<cnt;kk++) { \
1556 lua_pushnumber(L,(kk)); \
1557 lua_pushstring(L,item[kk]); \
1558 lua_rawset(L,-3); } \
1559 lua_setfield(L,-2,s); } }
1561 static void handle_fpst_rule(lua_State
* L
, struct fpst_rule
*rule
, int format
)
1565 if (format
== pst_glyphs
) {
1568 dump_stringfield(L
, "names", rule
->u
.glyph
.names
);
1569 dump_stringfield(L
, "back", rule
->u
.glyph
.back
);
1570 dump_stringfield(L
, "fore", rule
->u
.glyph
.fore
);
1571 lua_setfield(L
, -2, fpossub_format_enum
[format
]);
1573 } else if (format
== pst_class
) {
1576 DUMP_NUMBER_ARRAY("current", rule
->u
.class.ncnt
,
1577 rule
->u
.class.nclasses
);
1578 DUMP_NUMBER_ARRAY("before", rule
->u
.class.bcnt
, rule
->u
.class.bclasses
);
1579 DUMP_NUMBER_ARRAY("after", rule
->u
.class.fcnt
, rule
->u
.class.fclasses
);
1581 DUMP_NUMBER_ARRAY("allclasses", 0, rule
->u
.class.allclasses
);
1583 lua_setfield(L
, -2, fpossub_format_enum
[format
]);
1585 } else if (format
== pst_coverage
) {
1588 DUMP_STRING_ARRAY("current", rule
->u
.coverage
.ncnt
,
1589 rule
->u
.coverage
.ncovers
);
1590 DUMP_STRING_ARRAY("before", rule
->u
.coverage
.bcnt
,
1591 rule
->u
.coverage
.bcovers
);
1592 DUMP_STRING_ARRAY("after", rule
->u
.coverage
.fcnt
,
1593 rule
->u
.coverage
.fcovers
);
1594 lua_setfield(L
, -2, fpossub_format_enum
[format
]);
1596 } else if (format
== pst_reversecoverage
) {
1599 DUMP_STRING_ARRAY("current", rule
->u
.rcoverage
.always1
,
1600 rule
->u
.rcoverage
.ncovers
);
1601 DUMP_STRING_ARRAY("before", rule
->u
.rcoverage
.bcnt
,
1602 rule
->u
.rcoverage
.bcovers
);
1603 DUMP_STRING_ARRAY("after", rule
->u
.rcoverage
.fcnt
,
1604 rule
->u
.rcoverage
.fcovers
);
1605 dump_stringfield(L
, "replacements", rule
->u
.rcoverage
.replacements
);
1606 lua_setfield(L
, -2, fpossub_format_enum
[format
]);
1608 fprintf(stderr
, "handle_fpst_rule(): Unknown rule format: %d\n",
1612 if (rule
->lookup_cnt
> 0) {
1614 for (k
= 0; k
< rule
->lookup_cnt
; k
++) {
1615 lua_pushnumber(L
, (rule
->lookups
[k
].seq
+ 1));
1616 if (rule
->lookups
[k
].lookup
!= NULL
) {
1617 lua_pushstring(L
, rule
->lookups
[k
].lookup
->lookup_name
);
1623 lua_setfield(L
, -2, "lookups");
1625 /*fprintf(stderr,"handle_fpst_rule(): No lookups?\n"); */
1629 static void do_handle_generic_fpst(lua_State
* L
, struct generic_fpst
*fpst
)
1633 if (fpst
->type
> LAST_POSSUB_TYPE_ENUM
) {
1634 dump_intfield(L
, "type", fpst
->type
);
1636 dump_enumfield(L
, "type", fpst
->type
, possub_type_enum
);
1638 dump_enumfield(L
, "format", fpst
->format
, fpossub_format_enum
);
1640 if (fpst
->format
== pst_class
) {
1641 DUMP_EXACT_STRING_ARRAY("current_class", fpst
->nccnt
, fpst
->nclass
);
1642 DUMP_EXACT_STRING_ARRAY("before_class", fpst
->bccnt
, fpst
->bclass
);
1643 DUMP_EXACT_STRING_ARRAY("after_class", fpst
->fccnt
, fpst
->fclass
);
1645 DUMP_STRING_ARRAY("current_class", fpst
->nccnt
, fpst
->nclass
);
1646 DUMP_STRING_ARRAY("before_class", fpst
->bccnt
, fpst
->bclass
);
1647 DUMP_STRING_ARRAY("after_class", fpst
->fccnt
, fpst
->fclass
);
1650 lua_checkstack(L
, 4);
1651 if (fpst
->rule_cnt
> 0) {
1652 lua_createtable(L
, fpst
->rule_cnt
, 1);
1653 for (k
= 0; k
< fpst
->rule_cnt
; k
++) {
1654 lua_pushnumber(L
, (k
+ 1));
1656 handle_fpst_rule(L
, &(fpst
->rules
[k
]), fpst
->format
);
1659 lua_setfield(L
, -2, "rules");
1661 /*dump_intfield (L,"ticked", fpst->ticked); */
1664 static void handle_generic_fpst(lua_State
* L
, struct generic_fpst
*fpst
)
1666 struct generic_fpst
*next
;
1668 lua_checkstack(L
, 3);
1669 if (fpst
->subtable
!= NULL
&& fpst
->subtable
->subtable_name
!= NULL
) {
1670 lua_pushstring(L
, fpst
->subtable
->subtable_name
);
1672 lua_pushnumber(L
, k
);
1675 lua_createtable(L
, 0, 10);
1676 do_handle_generic_fpst(L
, fpst
);
1679 while (next
!= NULL
) {
1680 lua_checkstack(L
, 3);
1681 if (next
->subtable
!= NULL
&& next
->subtable
->subtable_name
!= NULL
) {
1682 lua_pushstring(L
, next
->subtable
->subtable_name
);
1684 lua_pushnumber(L
, k
);
1687 lua_createtable(L
, 0, 10);
1688 do_handle_generic_fpst(L
, next
);
1694 static void do_handle_otfname(lua_State
* L
, struct otfname
*oname
)
1696 dump_intfield(L
, "lang", oname
->lang
);
1697 dump_stringfield(L
, "name", oname
->name
);
1700 static void handle_otfname(lua_State
* L
, struct otfname
*oname
)
1702 struct otfname
*next
;
1703 NESTED_TABLE(do_handle_otfname
, oname
, 2);
1706 static void handle_MATH(lua_State
* L
, struct MATH
*MATH
)
1708 dump_intfield(L
, "ScriptPercentScaleDown", MATH
->ScriptPercentScaleDown
);
1709 dump_intfield(L
, "ScriptScriptPercentScaleDown", MATH
->ScriptScriptPercentScaleDown
);
1710 dump_intfield(L
, "DelimitedSubFormulaMinHeight", MATH
->DelimitedSubFormulaMinHeight
);
1711 dump_intfield(L
, "DisplayOperatorMinHeight", MATH
->DisplayOperatorMinHeight
);
1712 dump_intfield(L
, "MathLeading", MATH
->MathLeading
);
1713 dump_intfield(L
, "AxisHeight", MATH
->AxisHeight
);
1714 dump_intfield(L
, "AccentBaseHeight", MATH
->AccentBaseHeight
);
1715 dump_intfield(L
, "FlattenedAccentBaseHeight", MATH
->FlattenedAccentBaseHeight
);
1716 dump_intfield(L
, "SubscriptShiftDown", MATH
->SubscriptShiftDown
);
1717 dump_intfield(L
, "SubscriptTopMax", MATH
->SubscriptTopMax
);
1718 dump_intfield(L
, "SubscriptBaselineDropMin", MATH
->SubscriptBaselineDropMin
);
1719 dump_intfield(L
, "SuperscriptShiftUp", MATH
->SuperscriptShiftUp
);
1720 dump_intfield(L
, "SuperscriptShiftUpCramped", MATH
->SuperscriptShiftUpCramped
);
1721 dump_intfield(L
, "SuperscriptBottomMin", MATH
->SuperscriptBottomMin
);
1722 dump_intfield(L
, "SuperscriptBaselineDropMax", MATH
->SuperscriptBaselineDropMax
);
1723 dump_intfield(L
, "SubSuperscriptGapMin", MATH
->SubSuperscriptGapMin
);
1724 dump_intfield(L
, "SuperscriptBottomMaxWithSubscript", MATH
->SuperscriptBottomMaxWithSubscript
);
1725 dump_intfield(L
, "SpaceAfterScript", MATH
->SpaceAfterScript
);
1726 dump_intfield(L
, "UpperLimitGapMin", MATH
->UpperLimitGapMin
);
1727 dump_intfield(L
, "UpperLimitBaselineRiseMin", MATH
->UpperLimitBaselineRiseMin
);
1728 dump_intfield(L
, "LowerLimitGapMin", MATH
->LowerLimitGapMin
);
1729 dump_intfield(L
, "LowerLimitBaselineDropMin", MATH
->LowerLimitBaselineDropMin
);
1730 dump_intfield(L
, "StackTopShiftUp", MATH
->StackTopShiftUp
);
1731 dump_intfield(L
, "StackTopDisplayStyleShiftUp", MATH
->StackTopDisplayStyleShiftUp
);
1732 dump_intfield(L
, "StackBottomShiftDown", MATH
->StackBottomShiftDown
);
1733 dump_intfield(L
, "StackBottomDisplayStyleShiftDown", MATH
->StackBottomDisplayStyleShiftDown
);
1734 dump_intfield(L
, "StackGapMin", MATH
->StackGapMin
);
1735 dump_intfield(L
, "StackDisplayStyleGapMin", MATH
->StackDisplayStyleGapMin
);
1736 dump_intfield(L
, "StretchStackTopShiftUp", MATH
->StretchStackTopShiftUp
);
1737 dump_intfield(L
, "StretchStackBottomShiftDown", MATH
->StretchStackBottomShiftDown
);
1738 dump_intfield(L
, "StretchStackGapAboveMin", MATH
->StretchStackGapAboveMin
);
1739 dump_intfield(L
, "StretchStackGapBelowMin", MATH
->StretchStackGapBelowMin
);
1740 dump_intfield(L
, "FractionNumeratorShiftUp", MATH
->FractionNumeratorShiftUp
);
1741 dump_intfield(L
, "FractionNumeratorDisplayStyleShiftUp", MATH
->FractionNumeratorDisplayStyleShiftUp
);
1742 dump_intfield(L
, "FractionDenominatorShiftDown", MATH
->FractionDenominatorShiftDown
);
1743 dump_intfield(L
, "FractionDenominatorDisplayStyleShiftDown", MATH
->FractionDenominatorDisplayStyleShiftDown
);
1744 dump_intfield(L
, "FractionNumeratorGapMin", MATH
->FractionNumeratorGapMin
);
1745 dump_intfield(L
, "FractionNumeratorDisplayStyleGapMin", MATH
->FractionNumeratorDisplayStyleGapMin
);
1746 dump_intfield(L
, "FractionRuleThickness", MATH
->FractionRuleThickness
);
1747 dump_intfield(L
, "FractionDenominatorGapMin", MATH
->FractionDenominatorGapMin
);
1748 dump_intfield(L
, "FractionDenominatorDisplayStyleGapMin", MATH
->FractionDenominatorDisplayStyleGapMin
);
1749 dump_intfield(L
, "SkewedFractionHorizontalGap", MATH
->SkewedFractionHorizontalGap
);
1750 dump_intfield(L
, "SkewedFractionVerticalGap", MATH
->SkewedFractionVerticalGap
);
1751 dump_intfield(L
, "OverbarVerticalGap", MATH
->OverbarVerticalGap
);
1752 dump_intfield(L
, "OverbarRuleThickness", MATH
->OverbarRuleThickness
);
1753 dump_intfield(L
, "OverbarExtraAscender", MATH
->OverbarExtraAscender
);
1754 dump_intfield(L
, "UnderbarVerticalGap", MATH
->UnderbarVerticalGap
);
1755 dump_intfield(L
, "UnderbarRuleThickness", MATH
->UnderbarRuleThickness
);
1756 dump_intfield(L
, "UnderbarExtraDescender", MATH
->UnderbarExtraDescender
);
1757 dump_intfield(L
, "RadicalVerticalGap", MATH
->RadicalVerticalGap
);
1758 dump_intfield(L
, "RadicalDisplayStyleVerticalGap", MATH
->RadicalDisplayStyleVerticalGap
);
1759 dump_intfield(L
, "RadicalRuleThickness", MATH
->RadicalRuleThickness
);
1760 dump_intfield(L
, "RadicalExtraAscender", MATH
->RadicalExtraAscender
);
1761 dump_intfield(L
, "RadicalKernBeforeDegree", MATH
->RadicalKernBeforeDegree
);
1762 dump_intfield(L
, "RadicalKernAfterDegree", MATH
->RadicalKernAfterDegree
);
1763 dump_intfield(L
, "RadicalDegreeBottomRaisePercent", MATH
->RadicalDegreeBottomRaisePercent
);
1764 dump_intfield(L
, "MinConnectorOverlap", MATH
->MinConnectorOverlap
);
1767 /* the handling of BASE is untested, no font */
1768 static void handle_baselangextent(lua_State
* L
, struct baselangextent
*ble
);
1770 static void do_handle_baselangextent(lua_State
* L
, struct baselangextent
*ble
)
1772 dump_tag(L
, "tag", ble
->lang
);
1773 dump_intfield(L
, "ascent", ble
->ascent
);
1774 dump_intfield(L
, "descent", ble
->descent
);
1776 handle_baselangextent(L
, ble
->features
);
1777 lua_setfield(L
, -2, "features");
1780 static void handle_baselangextent(lua_State
* L
, struct baselangextent
*ble
)
1782 struct baselangextent
*next
;
1783 NESTED_TABLE(do_handle_baselangextent
, ble
, 4);
1786 static void handle_base(lua_State
* L
, struct Base
*Base
)
1789 struct basescript
*next
= Base
->scripts
;
1791 for (i
= 0; i
< Base
->baseline_cnt
; i
++) {
1792 lua_pushstring(L
, make_tag_string(Base
->baseline_tags
[i
]));
1793 lua_rawseti(L
, -2, (i
+ 1));
1795 lua_setfield(L
, -2, "tags");
1798 while (next
!= NULL
) {
1799 lua_pushstring(L
, make_tag_string(next
->script
));
1801 dump_intfield(L
, "default_baseline", (next
->def_baseline
+ 1));
1803 for (i
= 0; i
< Base
->baseline_cnt
; i
++) {
1804 if (next
->baseline_pos
!= NULL
) /* default omitted */
1805 lua_pushnumber(L
, next
->baseline_pos
[i
]);
1807 lua_pushnumber(L
, 0);
1808 lua_rawseti(L
, -2, (i
+ 1));
1810 lua_setfield(L
, -2, "baseline");
1812 handle_baselangextent(L
, next
->langs
);
1813 lua_setfield(L
, -2, "lang");
1817 lua_setfield(L
, -2, "scripts");
1821 static void handle_axismap(lua_State
* L
, struct axismap
*am
)
1824 lua_checkstack(L
, 3);
1826 for (i
= 0; i
< am
->points
; i
++) {
1827 lua_pushnumber(L
, am
->blends
[i
]);
1828 lua_rawseti(L
, -2, (i
+ 1));
1830 lua_setfield(L
, -2, "blends");
1832 for (i
= 0; i
< am
->points
; i
++) {
1833 lua_pushnumber(L
, am
->designs
[i
]);
1834 lua_rawseti(L
, -2, (i
+ 1));
1836 lua_setfield(L
, -2, "designs");
1837 dump_realfield(L
, "min", am
->min
);
1838 dump_realfield(L
, "def", am
->def
);
1839 dump_realfield(L
, "max", am
->max
);
1842 static void handle_mmset(lua_State
* L
, struct mmset
*mm
)
1846 for (i
= 0; i
< mm
->axis_count
; i
++) {
1847 lua_pushstring(L
, mm
->axes
[i
]);
1848 lua_rawseti(L
, -2, (i
+ 1));
1850 lua_setfield(L
, -2, "axes");
1852 dump_intfield(L
, "instance_count", mm
->instance_count
);
1853 /* SplineFont *normal; *//* this is the parent */
1854 if (mm
->instance_count
> 0) {
1856 for (i
= 0; i
< mm
->instance_count
* mm
->axis_count
; i
++) {
1857 lua_pushnumber(L
, mm
->positions
[i
]);
1858 lua_rawseti(L
, -2, (i
+ 1));
1860 lua_setfield(L
, -2, "positions");
1862 /* better not to do this */
1865 struct mmset
*mmsave
;
1867 for (i
= 0; i
< mm
->instance_count
; i
++) {
1868 lua_checkstack(L
, 20);
1869 lua_createtable(L
, 0, 60);
1870 mmsave
= mm
->instances
[i
]->mm
;
1871 mm
->instances
[i
]->mm
= NULL
;
1872 handle_splinefont(L
, mm
->instances
[i
]);
1873 mm
->instances
[i
]->mm
= mmsave
;
1874 lua_rawseti(L
, -2, (i
+ 1));
1876 lua_setfield(L
, -2, "instances");
1881 for (i
= 0; i
< mm
->instance_count
; i
++) {
1882 lua_pushnumber(L
, mm
->defweights
[i
]);
1883 lua_rawseti(L
, -2, (i
+ 1));
1885 lua_setfield(L
, -2, "defweights");
1888 if (mm
->axismaps
!= NULL
) {
1890 for (i
= 0; i
< mm
->axis_count
; i
++) {
1892 handle_axismap(L
, &(mm
->axismaps
[i
]));
1893 lua_rawseti(L
, -2, (i
+ 1));
1895 lua_setfield(L
, -2, "axismaps");
1897 dump_stringfield(L
, "cdv", mm
->cdv
);
1898 dump_stringfield(L
, "ndv", mm
->ndv
);
1901 static void handle_splinefont(lua_State
* L
, struct splinefont
*sf
)
1907 dump_stringfield(L
, "table_version", LUA_OTF_VERSION
);
1908 dump_stringfield(L
, "fontname", sf
->fontname
);
1909 dump_stringfield(L
, "fullname", sf
->fullname
);
1910 dump_stringfield(L
, "familyname", sf
->familyname
);
1911 dump_stringfield(L
, "weight", sf
->weight
);
1912 dump_stringfield(L
, "copyright", sf
->copyright
);
1913 dump_stringfield(L
, "filename", sf
->filename
);
1914 /* dump_stringfield(L,"defbasefilename", sf->defbasefilename); */
1915 dump_stringfield(L
, "version", sf
->version
);
1916 dump_floatfield(L
, "italicangle", sf
->italicangle
);
1917 dump_floatfield(L
, "upos", sf
->upos
);
1918 dump_floatfield(L
, "uwidth", sf
->uwidth
);
1919 dump_intfield(L
, "ascent", sf
->ascent
);
1920 dump_intfield(L
, "descent", sf
->descent
);
1921 if (sf
->uniqueid
!=0) {
1922 dump_intfield(L
, "uniqueid", sf
->uniqueid
);
1925 if (sf
->glyphcnt
> 0) {
1926 dump_intfield(L
, "glyphcnt", sf
->glyphmax
- sf
->glyphmin
+ 1);
1928 dump_intfield(L
, "glyphcnt", 0);
1931 dump_intfield(L
, "glyphmax", sf
->glyphmax
- 1);
1932 dump_intfield(L
, "glyphmin", sf
->glyphmin
);
1933 dump_intfield(L
, "units_per_em", sf
->units_per_em
);
1935 if (sf
->possub
!= NULL
) {
1937 handle_generic_fpst(L
, sf
->possub
);
1938 lua_setfield(L
, -2, "lookups");
1941 lua_checkstack(L
, 4);
1942 lua_createtable(L
, sf
->glyphcnt
, 0);
1944 /* This after-the-fact type discovery is not brilliant,
1945 I should really add a 'format' key in the structure */
1946 if ((sf
->origname
!= NULL
) &&
1947 (strmatch(sf
->origname
+ strlen(sf
->origname
) - 4, ".pfa") == 0 ||
1948 strmatch(sf
->origname
+ strlen(sf
->origname
) - 4, ".pfb") == 0)) {
1953 /* some code to ensure that the .notdef ends up in slot 0
1954 (this will actually be enforced by the CFF writer) */
1955 for (k
= 0; k
< sf
->glyphcnt
; k
++) {
1956 if (sf
->glyphs
[k
]) {
1957 if (strcmp(sf
->glyphs
[k
]->name
, ".notdef") == 0) {
1962 if (l
== -1) { /* fake a .notdef at the end */
1965 for (k
= 0; k
< l
; k
++) {
1966 if (sf
->glyphs
[k
]) {
1967 lua_pushnumber(L
, (k
+ 1));
1968 lua_createtable(L
, 0, 12);
1969 handle_splinechar(L
, sf
->glyphs
[k
], sf
->hasvmetrics
);
1973 if (sf
->glyphs
!= NULL
&& l
< sf
->glyphcnt
) {
1974 lua_pushnumber(L
, 0);
1975 if (sf
->glyphs
[l
]) {
1976 lua_createtable(L
, 0, 12);
1977 handle_splinechar(L
, sf
->glyphs
[l
], sf
->hasvmetrics
);
1979 lua_createtable(L
, 0, 0);
1984 if ((l
+ 1) < sf
->glyphcnt
) {
1985 for (k
= (l
+ 1); k
< sf
->glyphcnt
; k
++) {
1986 if (sf
->glyphs
[k
]) {
1987 lua_pushnumber(L
, k
);
1988 lua_createtable(L
, 0, 12);
1989 handle_splinechar(L
, sf
->glyphs
[k
], sf
->hasvmetrics
);
1994 lua_setfield(L
, -2, "glyphs");
1996 /* dump_intfield(L,"changed", sf->changed); */
1997 dump_intfield(L
, "hasvmetrics", sf
->hasvmetrics
);
1998 dump_intfield(L
, "onlybitmaps", sf
->onlybitmaps
);
1999 dump_intfield(L
, "serifcheck", sf
->serifcheck
);
2000 dump_intfield(L
, "isserif", sf
->isserif
);
2001 dump_intfield(L
, "issans", sf
->issans
);
2002 dump_intfield(L
, "encodingchanged", sf
->encodingchanged
);
2003 dump_intfield(L
, "strokedfont", sf
->strokedfont
);
2004 dump_intfield(L
, "use_typo_metrics", sf
->use_typo_metrics
);
2005 dump_intfield(L
, "weight_width_slope_only", sf
->weight_width_slope_only
);
2006 dump_intfield(L
, "head_optimized_for_cleartype",
2007 sf
->head_optimized_for_cleartype
);
2009 dump_enumfield(L
, "uni_interp", (sf
->uni_interp
+ 1), uni_interp_enum
);
2011 if (sf
->map
!= NULL
) {
2013 handle_encmap(L
, sf
->map
, l
);
2014 lua_setfield(L
, -2, "map");
2017 dump_stringfield(L
, "origname", sf
->origname
); /* new */
2019 if (sf
->private != NULL
) {
2021 handle_psdict(L
, sf
->private);
2022 lua_setfield(L
, -2, "private");
2025 dump_stringfield(L
, "xuid", sf
->xuid
);
2027 lua_createtable(L
, 0, 40);
2028 handle_pfminfo(L
, sf
->pfminfo
);
2029 lua_setfield(L
, -2, "pfminfo");
2031 if (sf
->names
!= NULL
) {
2033 handle_ttflangname(L
, sf
->names
);
2034 lua_setfield(L
, -2, "names");
2037 lua_createtable(L
, 0, 4);
2038 dump_stringfield(L
, "registry", sf
->cidregistry
);
2039 dump_stringfield(L
, "ordering", sf
->ordering
);
2040 dump_intfield(L
, "version", sf
->cidversion
);
2041 dump_intfield(L
, "supplement", sf
->supplement
);
2042 lua_setfield(L
, -2, "cidinfo");
2044 /* SplineFont *cidmaster *//* parent in a subfont */
2045 if (sf
->subfontcnt
> 0) {
2046 lua_createtable(L
, sf
->subfontcnt
, 0);
2047 for (k
= 0; k
< sf
->subfontcnt
; k
++) {
2048 lua_checkstack(L
, 10);
2050 handle_splinefont(L
, sf
->subfonts
[k
]);
2051 lua_rawseti(L
, -2, (k
+ 1));
2053 lua_setfield(L
, -2, "subfonts");
2056 dump_stringfield(L
, "comments", sf
->comments
);
2057 dump_stringfield(L
, "fontlog", sf
->fontlog
);
2059 if (sf
->cvt_names
!= NULL
) {
2061 for (k
= 0; sf
->cvt_names
[k
] != END_CVT_NAMES
; ++k
) {
2062 lua_pushstring(L
, sf
->cvt_names
[k
]);
2063 lua_rawseti(L
, -2, (k
+ 1));
2065 lua_setfield(L
, -2, "cvt_names");
2068 if (sf
->ttf_tables
!= NULL
) {
2070 handle_ttf_table(L
, sf
->ttf_tables
);
2071 lua_setfield(L
, -2, "ttf_tables");
2074 if (sf
->ttf_tab_saved
!= NULL
) {
2076 handle_ttf_table(L
, sf
->ttf_tab_saved
);
2077 lua_setfield(L
, -2, "ttf_tab_saved");
2080 if (sf
->texdata
.type
!= tex_unset
) {
2082 dump_enumfield(L
, "type", sf
->texdata
.type
, tex_type_enum
);
2084 for (k
= 0; k
< 22; k
++) {
2085 lua_pushnumber(L
, k
);
2086 lua_pushnumber(L
, sf
->texdata
.params
[k
]);
2089 lua_setfield(L
, -2, "params");
2090 lua_setfield(L
, -2, "texdata");
2092 if (sf
->anchor
!= NULL
) {
2094 handle_anchorclass(L
, sf
->anchor
);
2095 lua_setfield(L
, -2, "anchor_classes");
2097 if (sf
->kerns
!= NULL
) {
2099 handle_kernclass(L
, sf
->kerns
, NULL
);
2100 lua_setfield(L
, -2, "kerns");
2102 if (sf
->vkerns
!= NULL
) {
2104 handle_kernclass(L
, sf
->vkerns
, NULL
);
2105 lua_setfield(L
, -2, "vkerns");
2107 if (sf
->gsub_lookups
!= NULL
) {
2109 handle_lookup(L
, sf
->gsub_lookups
, sf
);
2110 lua_setfield(L
, -2, "gsub");
2112 if (sf
->gpos_lookups
!= NULL
) {
2114 handle_lookup(L
, sf
->gpos_lookups
, sf
);
2115 lua_setfield(L
, -2, "gpos");
2118 if (sf
->mm
!= NULL
) {
2120 handle_mmset(L
, sf
->mm
);
2121 lua_setfield(L
, -2, "mm");
2123 dump_stringfield(L
, "chosenname", sf
->chosenname
);
2125 if (sf
->macstyle
!=-1) {
2126 dump_intfield(L
, "macstyle", sf
->macstyle
);
2128 dump_stringfield(L
, "fondname", sf
->fondname
);
2130 dump_intfield(L
, "design_size", sf
->design_size
);
2131 dump_intfield(L
, "fontstyle_id", sf
->fontstyle_id
);
2133 if (sf
->fontstyle_name
!= NULL
) {
2135 handle_otfname(L
, sf
->fontstyle_name
);
2136 lua_setfield(L
, -2, "fontstyle_name");
2139 dump_intfield(L
, "design_range_bottom", sf
->design_range_bottom
);
2140 dump_intfield(L
, "design_range_top", sf
->design_range_top
);
2141 dump_floatfield(L
, "strokewidth", sf
->strokewidth
);
2143 if (sf
->mark_class_cnt
> 0) {
2145 for (k
= 0; k
< sf
->mark_class_cnt
; k
++) {
2146 if (sf
->mark_class_names
[k
] != NULL
) {
2147 lua_pushstring(L
, sf
->mark_class_names
[k
]);
2148 lua_pushstring(L
, sf
->mark_classes
[k
]);
2152 lua_setfield(L
, -2, "mark_classes");
2155 dump_uintfield(L
, "creationtime", sf
->creationtime
);
2156 dump_uintfield(L
, "modificationtime", sf
->modificationtime
);
2158 dump_intfield(L
, "os2_version", sf
->os2_version
);
2159 dump_intfield(L
, "sfd_version", sf
->sfd_version
);
2161 if (sf
->MATH
!= NULL
) {
2163 handle_MATH(L
, sf
->MATH
);
2164 lua_setfield(L
, -2, "math");
2167 if (sf
->loadvalidation_state
!= 0) {
2171 st
= sf
->loadvalidation_state
;
2172 if (st
& lvs_bad_ps_fontname
) {
2173 lua_pushliteral(L
, "bad_ps_fontname");
2174 lua_rawseti(L
, -2, val
++);
2176 if (st
& lvs_bad_glyph_table
) {
2177 lua_pushliteral(L
, "bad_glyph_table");
2178 lua_rawseti(L
, -2, val
++);
2180 if (st
& lvs_bad_cff_table
) {
2181 lua_pushliteral(L
, "bad_cff_table");
2182 lua_rawseti(L
, -2, val
++);
2184 if (st
& lvs_bad_metrics_table
) {
2185 lua_pushliteral(L
, "bad_metrics_table");
2186 lua_rawseti(L
, -2, val
++);
2188 if (st
& lvs_bad_cmap_table
) {
2189 lua_pushliteral(L
, "bad_cmap_table");
2190 lua_rawseti(L
, -2, val
++);
2192 if (st
& lvs_bad_bitmaps_table
) {
2193 lua_pushliteral(L
, "bad_bitmaps_table");
2194 lua_rawseti(L
, -2, val
++);
2196 if (st
& lvs_bad_gx_table
) {
2197 lua_pushliteral(L
, "bad_gx_table");
2198 lua_rawseti(L
, -2, val
++);
2200 if (st
& lvs_bad_ot_table
) {
2201 lua_pushliteral(L
, "bad_ot_table");
2202 lua_rawseti(L
, -2, val
++);
2204 if (st
& lvs_bad_os2_version
) {
2205 lua_pushliteral(L
, "bad_os2_version");
2206 lua_rawseti(L
, -2, val
++);
2208 if (st
& lvs_bad_sfnt_header
) {
2209 lua_pushliteral(L
, "bad_sfnt_header");
2210 lua_rawseti(L
, -2, val
++);
2212 lua_setfield(L
, -2, "validation_state");
2215 if (sf
->horiz_base
!= NULL
) {
2217 handle_base(L
, sf
->horiz_base
);
2218 lua_setfield(L
, -2, "horiz_base");
2220 if (sf
->vert_base
!= NULL
) {
2222 handle_base(L
, sf
->vert_base
);
2223 lua_setfield(L
, -2, "vert_base");
2225 dump_intfield(L
, "extrema_bound", sf
->extrema_bound
);
2228 static int ff_make_table(lua_State
* L
)
2231 sf
= *(check_isfont(L
, 1));
2233 lua_pushboolean(L
, 0);
2235 lua_createtable(L
, 0, 60);
2236 handle_splinefont(L
, sf
);
2241 static void do_ff_info(lua_State
* L
, SplineFont
* sf
)
2244 dump_stringfield(L
, "familyname", sf
->familyname
);
2245 dump_stringfield(L
, "fontname", sf
->fontname
);
2246 dump_stringfield(L
, "fullname", sf
->fullname
);
2247 dump_floatfield(L
, "italicangle", sf
->italicangle
);
2248 dump_stringfield(L
, "version", sf
->version
);
2249 dump_stringfield(L
, "weight", sf
->weight
);
2251 dump_intfield(L
, "units_per_em", sf
->units_per_em
);
2252 /* These are not assigned in info... */
2253 /*dump_intfield(L, "design_range_bottom", sf->design_range_bottom);*/
2254 /*dump_intfield(L, "design_range_top", sf->design_range_top);*/
2255 /*dump_intfield(L, "design_size", sf->design_size);*/
2257 lua_createtable(L
, 0, 40);
2258 handle_pfminfo(L
, sf
->pfminfo
);
2259 lua_setfield(L
, -2, "pfminfo");
2261 /* Do we need this ? */
2262 if (sf
->names
!= NULL
) {
2264 handle_ttflangname(L
, sf
->names
);
2265 lua_setfield(L
, -2, "names");
2270 FK_table_version
= 0,
2297 FK_use_typo_metrics
,
2298 FK_weight_width_slope_only
,
2299 FK_head_optimized_for_cleartype
,
2320 /* FK_sm, */ /*this was removed because AAT is not supported anymore*/
2329 FK_design_range_bottom
,
2330 FK_design_range_top
,
2334 FK_modificationtime
,
2338 FK_validation_state
,
2344 const char *font_keys
[] = {
2373 "weight_width_slope_only",
2374 "head_optimized_for_cleartype",
2403 "design_range_bottom",
2438 GK_is_extended_shape
,
2439 GK_italic_correction
,
2445 } font_glyph_key_values
;
2447 const char *font_glyph_keys
[] = {
2465 "is_extended_shape",
2466 "italic_correction",
2475 static int ff_fields(lua_State
* L
)
2478 const char **fields
= NULL
;
2479 if (is_userdata(L
, 1, FONT_METATABLE
) ||
2480 is_userdata(L
, 1, FONT_SUBFONT_METATABLE
)) {
2482 } else if (is_userdata(L
, 1, FONT_GLYPH_METATABLE
)) {
2483 fields
= font_glyph_keys
;
2485 if (fields
!= NULL
) {
2487 for (i
= 0; fields
[i
] != NULL
; i
++) {
2488 lua_pushstring(L
, fields
[i
]);
2489 lua_rawseti(L
, -2, (i
+ 1));
2497 static int ff_glyphs_index(lua_State
* L
)
2504 lua_pushstring(L
, "__sf");
2506 /* sf = *check_isfont(L, -1); */
2507 if (!(is_userdata(L
, -1, FONT_METATABLE
) ||
2508 is_userdata(L
, -1, FONT_SUBFONT_METATABLE
))) {
2509 return luaL_error(L
, "fontloader.__index: expected a (sub)font userdata object\n");
2511 sf
= *((SplineFont
**)lua_touserdata(L
, -1));
2514 gid
= luaL_checkinteger(L
, 2);
2515 /* if (gid < sf->glyphmin || gid >= sf->glyphmax) {*/
2516 if (gid
< sf
->glyphmin
|| gid
> sf
->glyphmax
) {
2517 return luaL_error(L
, "fontloader.glyphs.__index: index is invalid\n");
2519 /* This after-the-fact type discovery is not brilliant,
2520 I should really add a 'format' key in the structure */
2521 if ((sf
->origname
!= NULL
) &&
2522 (strmatch(sf
->origname
+ strlen(sf
->origname
) - 4, ".pfa") == 0 ||
2523 strmatch(sf
->origname
+ strlen(sf
->origname
) - 4, ".pfb") == 0)) {
2526 /* some code to ensure that the .notdef ends up in slot 0
2527 (this will actually be enforced by the CFF writer) */
2530 /* now l is the .notdef location, adjust gid if needed */
2531 if (l
== sf
->glyphcnt
) { /* no .notdef at all, will be created at zero */
2533 gid
= l
; /* .notdef was added at end */
2535 gid
--; /* f.glyphs[gid] == sf->glyphs[gid-1] */
2537 } else if (l
!= 0) {
2540 } else if (gid
< l
) {
2545 /* push the glyph */
2546 if (sf
->glyphs
[gid
] && sf
->glyphs
[gid
] != (struct splinechar
*)-1) {
2547 lua_ff_pushglyph(L
, sf
->glyphs
[gid
]);
2554 static int ff_glyph_index(lua_State
* L
)
2556 struct splinechar
*glyph
;
2558 glyph
= *check_isglyph(L
, 1);
2559 if (glyph
== NULL
) {
2560 return luaL_error(L
, "fontloader.glyph.__index: glyph is nonexistent\n");
2562 if (lua_type(L
, 2) != LUA_TSTRING
) { /* 1 == 'font' */
2563 return luaL_error(L
, "fontloader.glyph.__index: can only be indexed by string\n");
2565 key
= luaL_checkoption(L
, 2, NULL
, font_glyph_keys
);
2568 lua_pushstring(L
, glyph
->name
);
2571 lua_pushnumber(L
, glyph
->unicodeenc
);
2573 case GK_boundingbox
:
2574 if (glyph
->xmax
== 0 && glyph
->ymax
== 0 && glyph
->xmin
== 0
2575 && glyph
->ymin
== 0) {
2577 SplineCharFindBounds(glyph
, &bb
);
2578 glyph
->xmin
= bb
.minx
;
2579 glyph
->ymin
= bb
.miny
;
2580 glyph
->xmax
= bb
.maxx
;
2581 glyph
->ymax
= bb
.maxy
;
2583 lua_createtable(L
, 4, 0);
2584 lua_pushnumber(L
, 1);
2585 lua_pushnumber(L
, glyph
->xmin
);
2587 lua_pushnumber(L
, 2);
2588 lua_pushnumber(L
, glyph
->ymin
);
2590 lua_pushnumber(L
, 3);
2591 lua_pushnumber(L
, glyph
->xmax
);
2593 lua_pushnumber(L
, 4);
2594 lua_pushnumber(L
, glyph
->ymax
);
2598 lua_pushnumber(L
, glyph
->vwidth
);
2601 lua_pushnumber(L
, glyph
->width
);
2603 case GK_lsidebearing
:
2604 lua_pushnumber(L
, glyph
->lsidebearing
);
2607 if (glyph
->glyph_class
> 0) {
2608 lua_pushstring(L
, glyph_class_enum
[glyph
->glyph_class
]);
2614 if (glyph
->kerns
!= NULL
) {
2616 handle_kernpair(L
, glyph
->kerns
);
2622 if (glyph
->vkerns
!= NULL
) {
2624 handle_kernpair(L
, glyph
->vkerns
);
2630 if (glyph
->dependents
!= NULL
) {
2632 handle_splinecharlist(L
, glyph
->dependents
);
2638 if (glyph
->possub
!= NULL
) {
2640 handle_generic_pst(L
, glyph
->possub
);
2646 if (glyph
->ligofme
!= NULL
) {
2648 handle_liglist(L
, glyph
->ligofme
);
2654 lua_pushstring(L
, glyph
->comment
);
2657 if (glyph
->anchor
!= NULL
) {
2659 handle_anchorpoint(L
, glyph
->anchor
);
2665 if (glyph
->altuni
!= NULL
) {
2667 handle_altuni(L
, glyph
->altuni
);
2673 if (glyph
->tex_height
!= TEX_UNDEF
) {
2674 lua_pushnumber(L
, glyph
->tex_height
);
2680 if (glyph
->tex_height
!= TEX_UNDEF
) {
2681 lua_pushnumber(L
, glyph
->tex_depth
);
2686 case GK_is_extended_shape
:
2687 lua_pushnumber(L
, glyph
->is_extended_shape
);
2689 case GK_italic_correction
:
2690 if (glyph
->italic_correction
!= TEX_UNDEF
) {
2691 lua_pushnumber(L
, glyph
->italic_correction
);
2697 if (glyph
->top_accent_horiz
!= TEX_UNDEF
) {
2698 lua_pushnumber(L
, glyph
->top_accent_horiz
);
2703 case GK_vert_variants
:
2704 if (glyph
->vert_variants
!= NULL
) {
2706 handle_glyphvariants(L
, glyph
->vert_variants
);
2711 case GK_horiz_variants
:
2712 if (glyph
->horiz_variants
!= NULL
) {
2714 handle_glyphvariants(L
, glyph
->horiz_variants
);
2720 if (glyph
->mathkern
!= NULL
) {
2722 handle_mathkern(L
, glyph
->mathkern
);
2728 if (glyph
->orig_pos
>=0) {
2729 lua_pushnumber(L
, glyph
->orig_pos
);
2740 static int ff_index(lua_State
* L
)
2744 /* sf = *check_isfont(L, 1); */
2745 if (!(is_userdata(L
, 1, FONT_METATABLE
) ||
2746 is_userdata(L
, 1, FONT_SUBFONT_METATABLE
))) {
2747 return luaL_error(L
, "fontloader.__index: expected a (sub)font userdata object\n");
2749 sf
= *((SplineFont
**)lua_touserdata(L
, 1));
2755 if (lua_type(L
, 2) != LUA_TSTRING
) { /* 1 == 'font' */
2756 return luaL_error(L
, "fontloader.__index: can only be indexed by string\n");
2758 key
= luaL_checkoption(L
, 2, NULL
, font_keys
);
2760 case FK_table_version
:
2761 lua_pushstring(L
, LUA_OTF_VERSION
);
2764 lua_pushstring(L
, sf
->fontname
);
2767 lua_pushstring(L
, sf
->fullname
);
2770 lua_pushstring(L
, sf
->familyname
);
2773 lua_pushstring(L
, sf
->weight
);
2776 lua_pushstring(L
, sf
->copyright
);
2779 lua_pushstring(L
, sf
->filename
);
2782 lua_pushstring(L
, sf
->version
);
2784 case FK_italicangle
:
2785 lua_pushnumber(L
, sf
->italicangle
);
2788 lua_pushnumber(L
, sf
->upos
);
2791 lua_pushnumber(L
, sf
->uwidth
);
2794 lua_pushnumber(L
, sf
->ascent
);
2797 lua_pushnumber(L
, sf
->descent
);
2800 lua_pushnumber(L
, sf
->uniqueid
);
2803 if (sf
->glyphcnt
> 0) {
2804 lua_pushnumber(L
, sf
->glyphmax
- sf
->glyphmin
+ 1);
2806 lua_pushnumber(L
, 0);
2810 lua_pushnumber(L
, sf
->glyphmax
- 1);
2813 lua_pushnumber(L
, sf
->glyphmin
);
2815 case FK_units_per_em
:
2816 lua_pushnumber(L
, sf
->units_per_em
);
2819 if (sf
->possub
!= NULL
) {
2821 handle_generic_fpst(L
, sf
->possub
);
2827 lua_newtable(L
); /* the virtual glyph table */
2828 lua_pushstring(L
, "__sf");
2829 lua_pushvalue(L
, 1); /* that is our font */
2831 luaL_getmetatable(L
, FONT_GLYPHS_METATABLE
);
2832 lua_setmetatable(L
, -2); /* assign the metatable */
2834 case FK_hasvmetrics
:
2835 lua_pushnumber(L
, sf
->hasvmetrics
);
2837 case FK_onlybitmaps
:
2838 lua_pushnumber(L
, sf
->onlybitmaps
);
2841 lua_pushnumber(L
, sf
->serifcheck
);
2844 lua_pushnumber(L
, sf
->isserif
);
2847 lua_pushnumber(L
, sf
->issans
);
2849 case FK_encodingchanged
:
2850 lua_pushnumber(L
, sf
->encodingchanged
);
2852 case FK_strokedfont
:
2853 lua_pushnumber(L
, sf
->strokedfont
);
2855 case FK_use_typo_metrics
:
2856 lua_pushnumber(L
, sf
->use_typo_metrics
);
2858 case FK_weight_width_slope_only
:
2859 lua_pushnumber(L
, sf
->weight_width_slope_only
);
2861 case FK_head_optimized_for_cleartype
:
2862 lua_pushnumber(L
, sf
->head_optimized_for_cleartype
);
2865 lua_pushstring(L
, uni_interp_enum
[(sf
->uni_interp
+ 1)]);
2868 if (sf
->map
!= NULL
) {
2870 handle_encmap(L
, sf
->map
, notdef_loc(sf
));
2876 lua_pushstring(L
, sf
->origname
);
2879 if (sf
->private != NULL
) {
2881 handle_psdict(L
, sf
->private);
2887 lua_pushstring(L
, sf
->xuid
);
2890 lua_createtable(L
, 0, 40);
2891 handle_pfminfo(L
, sf
->pfminfo
);
2894 if (sf
->names
!= NULL
) {
2896 handle_ttflangname(L
, sf
->names
);
2902 lua_createtable(L
, 0, 4);
2903 dump_stringfield(L
, "registry", sf
->cidregistry
);
2904 dump_stringfield(L
, "ordering", sf
->ordering
);
2905 dump_intfield(L
, "version", sf
->cidversion
);
2906 dump_intfield(L
, "supplement", sf
->supplement
);
2909 if (sf
->subfontcnt
> 0) {
2910 lua_createtable(L
, sf
->subfontcnt
, 0);
2911 for (k
= 0; k
< sf
->subfontcnt
; k
++) {
2912 lua_ff_pushsubfont(L
, sf
->subfonts
[k
]);
2913 lua_rawseti(L
, -2, (k
+ 1));
2920 lua_pushstring(L
, sf
->comments
);
2923 lua_pushstring(L
, sf
->fontlog
);
2926 if (sf
->cvt_names
!= NULL
) {
2928 for (k
= 0; sf
->cvt_names
[k
] != END_CVT_NAMES
; ++k
) {
2929 lua_pushstring(L
, sf
->cvt_names
[k
]);
2930 lua_rawseti(L
, -2, (k
+ 1));
2937 if (sf
->ttf_tables
!= NULL
) {
2939 handle_ttf_table(L
, sf
->ttf_tables
);
2944 case FK_ttf_tab_saved
:
2945 if (sf
->ttf_tab_saved
!= NULL
) {
2947 handle_ttf_table(L
, sf
->ttf_tab_saved
);
2953 if (sf
->texdata
.type
!= tex_unset
) {
2955 dump_enumfield(L
, "type", sf
->texdata
.type
, tex_type_enum
);
2957 for (k
= 0; k
< 22; k
++) {
2958 lua_pushnumber(L
, k
);
2959 lua_pushnumber(L
, sf
->texdata
.params
[k
]);
2962 lua_setfield(L
, -2, "params");
2967 case FK_anchor_classes
:
2968 if (sf
->anchor
!= NULL
) {
2970 handle_anchorclass(L
, sf
->anchor
);
2976 if (sf
->kerns
!= NULL
) {
2978 handle_kernclass(L
, sf
->kerns
, NULL
);
2984 if (sf
->vkerns
!= NULL
) {
2986 handle_kernclass(L
, sf
->vkerns
, NULL
);
2992 if (sf
->gsub_lookups
!= NULL
) {
2994 handle_lookup(L
, sf
->gsub_lookups
, sf
);
3000 if (sf
->gpos_lookups
!= NULL
) {
3002 handle_lookup(L
, sf
->gpos_lookups
, sf
);
3008 if (sf
->mm
!= NULL
) {
3010 handle_mmset(L
, sf
->mm
);
3016 lua_pushstring(L
, sf
->chosenname
);
3019 lua_pushnumber(L
, sf
->macstyle
);
3022 lua_pushstring(L
, sf
->fondname
);
3024 case FK_design_size
:
3025 lua_pushnumber(L
, sf
->design_size
);
3027 case FK_fontstyle_id
:
3028 lua_pushnumber(L
, sf
->fontstyle_id
);
3030 case FK_fontstyle_name
:
3031 if (sf
->fontstyle_name
!= NULL
) {
3033 handle_otfname(L
, sf
->fontstyle_name
);
3038 case FK_design_range_bottom
:
3039 lua_pushnumber(L
, sf
->design_range_bottom
);
3041 case FK_design_range_top
:
3042 lua_pushnumber(L
, sf
->design_range_top
);
3044 case FK_strokewidth
:
3045 lua_pushnumber(L
, sf
->strokewidth
);
3047 case FK_mark_classes
:
3048 if (sf
->mark_class_cnt
> 0) {
3050 for (k
= 0; k
< sf
->mark_class_cnt
; k
++) {
3051 if (sf
->mark_class_names
[k
] != NULL
) {
3052 lua_pushstring(L
, sf
->mark_class_names
[k
]);
3053 lua_pushstring(L
, sf
->mark_classes
[k
]);
3061 case FK_creationtime
:
3062 lua_pushnumber(L
, sf
->creationtime
);
3064 case FK_modificationtime
:
3065 lua_pushnumber(L
, sf
->modificationtime
);
3067 case FK_os2_version
:
3068 lua_pushnumber(L
, sf
->os2_version
);
3070 case FK_sfd_version
:
3071 lua_pushnumber(L
, sf
->sfd_version
);
3074 if (sf
->MATH
!= NULL
) {
3076 handle_MATH(L
, sf
->MATH
);
3081 case FK_validation_state
:
3082 if (sf
->loadvalidation_state
!= 0) {
3086 st
= sf
->loadvalidation_state
;
3087 if (st
& lvs_bad_ps_fontname
) {
3088 lua_pushliteral(L
, "bad_ps_fontname");
3089 lua_rawseti(L
, -2, val
++);
3091 if (st
& lvs_bad_glyph_table
) {
3092 lua_pushliteral(L
, "bad_glyph_table");
3093 lua_rawseti(L
, -2, val
++);
3095 if (st
& lvs_bad_cff_table
) {
3096 lua_pushliteral(L
, "bad_cff_table");
3097 lua_rawseti(L
, -2, val
++);
3099 if (st
& lvs_bad_metrics_table
) {
3100 lua_pushliteral(L
, "bad_metrics_table");
3101 lua_rawseti(L
, -2, val
++);
3103 if (st
& lvs_bad_cmap_table
) {
3104 lua_pushliteral(L
, "bad_cmap_table");
3105 lua_rawseti(L
, -2, val
++);
3107 if (st
& lvs_bad_bitmaps_table
) {
3108 lua_pushliteral(L
, "bad_bitmaps_table");
3109 lua_rawseti(L
, -2, val
++);
3111 if (st
& lvs_bad_gx_table
) {
3112 lua_pushliteral(L
, "bad_gx_table");
3113 lua_rawseti(L
, -2, val
++);
3115 if (st
& lvs_bad_ot_table
) {
3116 lua_pushliteral(L
, "bad_ot_table");
3117 lua_rawseti(L
, -2, val
++);
3119 if (st
& lvs_bad_os2_version
) {
3120 lua_pushliteral(L
, "bad_os2_version");
3121 lua_rawseti(L
, -2, val
++);
3123 if (st
& lvs_bad_sfnt_header
) {
3124 lua_pushliteral(L
, "bad_sfnt_header");
3125 lua_rawseti(L
, -2, val
++);
3132 if (sf
->horiz_base
!= NULL
) {
3134 handle_base(L
, sf
->horiz_base
);
3140 if (sf
->vert_base
!= NULL
) {
3142 handle_base(L
, sf
->vert_base
);
3147 case FK_extrema_bound
:
3148 lua_pushnumber(L
, sf
->extrema_bound
);
3151 /* can't actually happen, |luaL_checkoption| raises an error instead */
3158 static int ff_info(lua_State
* L
)
3163 const char *fontname
;
3166 fontname
= luaL_checkstring(L
, 1);
3167 if (!strlen(fontname
)) {
3169 lua_pushfstring(L
, "font loading failed: empty string given\n", fontname
);
3172 /* test fontname for existance */
3173 if ((l
= fopen(fontname
, "r"))) {
3174 recorder_record_input(fontname
);
3178 lua_pushfstring(L
, "font loading failed for %s (read error)\n", fontname
);
3181 gww_error_count
= 0;
3182 fontnamecopy
= xstrdup(fontname
);
3183 sf
= ReadSplineFontInfo(fontnamecopy
, openflags
);
3185 if (gww_error_count
> 0)
3190 lua_pushfstring(L
, "font loading failed for %s\n", fontname
);
3193 if (sf
->next
!= NULL
) {
3194 SplineFont
*sf_next
;
3199 lua_rawseti(L
, -2, i
);
3202 EncMapFree(sf
->map
);
3208 EncMapFree(sf
->map
);
3215 static void ff_do_cff(SplineFont
* sf
, char *filename
, unsigned char **buf
,
3219 int32
*bsizes
= NULL
;
3220 int flags
= ps_flag_nocffsugar
+ ps_flag_nohints
;
3223 map
= EncMap1to1(sf
->glyphcnt
);
3226 (filename
, sf
, ff_cff
, bsizes
, bf_none
, flags
, map
, ly_fore
)) {
3228 f
= fopen(filename
, "rb");
3229 recorder_record_input(filename
);
3230 readbinfile(f
, buf
, bufsiz
);
3231 /*fprintf(stdout,"\n%s => CFF, size: %d\n", sf->filename, *bufsiz); */
3235 /* snprintf(errmsg, 255, "%s => CFF, failed", sf->filename); */
3236 /* normal_error("fontloader",errmsg); */ /* TODO */
3237 fprintf(stdout
,"%s => CFF, failed", sf
->filename
);
3241 /* exported for writecff.c */
3243 int ff_createcff(char *file
, unsigned char **buf
, int *bufsiz
)
3247 char s
[] = "tempfile.cff";
3250 sf
= ReadSplineFont(file
, openflags
);
3252 /* this is not the best way. nicer to have no temp file at all */
3253 ff_do_cff(sf
, s
, buf
, bufsiz
);
3254 for (k
= 0; k
< sf
->glyphcnt
; k
++) {
3255 if (sf
->glyphs
[k
] && strcmp(sf
->glyphs
[k
]->name
, ".notdef") == 0) {
3261 EncMapFree(sf
->map
);
3267 int ff_get_ttc_index(char *ffname
, char *psname
)
3274 sf
= ReadSplineFontInfo((char *) ffname
, openflags
);
3276 /* normal_error("fontloader","font loading failed unexpectedly"); */ /* TODO */
3277 fprintf(stdout
,"font loading failed unexpectedly\n");
3280 while (sf
!= NULL
) {
3281 if (strcmp(sf
->fontname
, psname
) == 0) {
3292 static struct luaL_Reg fllib
[] = {
3295 {"close", ff_close
},
3296 {"fields", ff_fields
},
3297 {"apply_afmfile", ff_apply_afmfile
},
3298 {"apply_featurefile", ff_apply_featurefile
},
3299 {"to_table", ff_make_table
},
3303 static const struct luaL_Reg fflib_m
[] = {
3304 {"__gc", ff_close
}, /* doesnt work yet! */
3305 {"__index", ff_index
},
3306 {NULL
, NULL
} /* sentinel */
3309 int luaopen_ff(lua_State
* L
)
3311 static char coord_sep_string
[] = ",";
3312 static char SaveTablesPref_string
[] = "VORG,JSTF,acnt,bsln,fdsc,fmtx,hsty,just,trak,Zapf,LINO";
3314 setlocale(LC_ALL
, "C"); /* undo whatever InitSimpleStuff has caused */
3315 coord_sep
= coord_sep_string
;
3316 FF_SetUiInterface(&luaui_interface
);
3317 default_encoding
= FindOrMakeEncoding("ISO8859-1");
3318 SaveTablesPref
= SaveTablesPref_string
;
3319 luaL_newmetatable(L
, FONT_METATABLE
);
3320 luaL_register(L
, NULL
, fflib_m
);
3322 /* virtual subfont table */
3323 luaL_newmetatable(L
, FONT_SUBFONT_METATABLE
);
3324 lua_pushstring(L
, "__index");
3325 lua_pushcfunction(L
, ff_index
);
3328 /* virtual glyphs table */
3329 luaL_newmetatable(L
, FONT_GLYPHS_METATABLE
);
3330 lua_pushstring(L
, "__index");
3331 lua_pushcfunction(L
, ff_glyphs_index
);
3334 /* virtual glyph table */
3335 luaL_newmetatable(L
, FONT_GLYPH_METATABLE
);
3336 lua_pushstring(L
, "__index");
3337 lua_pushcfunction(L
, ff_glyph_index
);
3341 luaL_openlib(L
, "fontloader", fllib
, 0);