>From 81022d5f885626cd64188f8448b33df0fb065317 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20Fabian=20Kr=C3=BCger?= Date: Mon, 21 Jan 2019 22:00:11 +0100 Subject: [PATCH] Node fonts --- source/texk/web2c/luatexdir/font/luafont.c | 26 ++- source/texk/web2c/luatexdir/font/texfont.c | 2 +- source/texk/web2c/luatexdir/font/texfont.h | 7 +- source/texk/web2c/luatexdir/font/writet3.c | 138 ++++++++++++--- source/texk/web2c/luatexdir/pdf/pdffont.c | 3 + source/texk/web2c/luatexdir/pdf/pdfgen.c | 170 ++++++++++++++----- source/texk/web2c/luatexdir/pdf/pdfgen.h | 2 + source/texk/web2c/luatexdir/pdf/pdfglyph.c | 25 +++ source/texk/web2c/luatexdir/pdf/pdfglyph.h | 1 + source/texk/web2c/luatexdir/pdf/pdfshipout.c | 8 +- source/texk/web2c/luatexdir/pdf/pdftypes.h | 5 +- source/texk/web2c/luatexdir/ptexlib.h | 7 +- 12 files changed, 302 insertions(+), 92 deletions(-) diff --git a/source/texk/web2c/luatexdir/font/luafont.c b/source/texk/web2c/luatexdir/font/luafont.c index 62edb1758..96ef0e8d6 100644 --- a/source/texk/web2c/luatexdir/font/luafont.c +++ b/source/texk/web2c/luatexdir/font/luafont.c @@ -43,7 +43,7 @@ const char *font_identity_strings[] = { }; const char *font_format_strings[] = { - "unknown", "type1", "type3", "truetype", "opentype", NULL + "unknown", "type1", "type3", "truetype", "opentype", "node", NULL }; const char *font_embedding_strings[] = { @@ -198,7 +198,9 @@ static void font_char_to_lua(lua_State * L, internal_font_number f, charinfo * c if (get_charinfo_rp(co) != 0) { dump_intfield(L,right_protruding,get_charinfo_rp(co)); } - if (font_encodingbytes(f) == 2) { + if (font_format(f) == node_format) { + dump_intfield(L,node,get_charinfo_index(co)); + } else if (font_encodingbytes(f) == 2) { dump_intfield(L,index,get_charinfo_index(co)); } if (get_charinfo_name(co) != NULL) { @@ -1130,7 +1132,7 @@ static void store_math_kerns(lua_State * L, int index, charinfo * co, int id) lua_pop(L, 1); } -static void font_char_from_lua(lua_State * L, internal_font_number f, int i, int *l_fonts, boolean has_math) +static void font_char_from_lua(lua_State * L, internal_font_number f, int i, int *l_fonts, boolean has_math, boolean is_nodefont) { int k, r, t, lt, u, n; charinfo *co; @@ -1157,7 +1159,11 @@ static void font_char_from_lua(lua_State * L, internal_font_number f, int i, int set_charinfo_italic(co, j); j = lua_numeric_field_by_index(L, lua_key_index(vert_italic), 0); set_charinfo_vert_italic(co, j); - j = lua_numeric_field_by_index(L, lua_key_index(index), 0); + if (is_nodefont) { + j = lua_numeric_field_by_index(L, lua_key_index(node), 0); + } else { + j = (unsigned short) lua_numeric_field_by_index(L, lua_key_index(index), 0); + } set_charinfo_index(co, j); j = lua_numeric_field_by_index(L, lua_key_index(expansion_factor), 1000); set_charinfo_ef(co, j); @@ -1455,6 +1461,7 @@ int font_from_lua(lua_State * L, int f) int *l_fonts = NULL; int save_ref ; boolean no_math = false; + boolean is_nodefont = false; /*tex Will we save a cache of the \LUA\ table? */ save_ref = 1; ss = NULL; @@ -1545,6 +1552,9 @@ int font_from_lua(lua_State * L, int f) set_font_type(f, i); i = n_enum_field(L, lua_key_index(format), unknown_format, font_format_strings); set_font_format(f, i); + if (i == node_format) { + is_nodefont = true; + } i = n_enum_field(L, lua_key_index(writingmode), unknown_writingmode, font_writingmode_strings); set_font_writingmode(f, i); i = n_enum_field(L, lua_key_index(identity), unknown_identity, font_identity_strings); @@ -1664,14 +1674,14 @@ int font_from_lua(lua_State * L, int f) if (lt == LUA_TNUMBER) { i = (int) lua_tointeger(L, -2); if (i >= 0) { - font_char_from_lua(L, f, i, l_fonts, !no_math); + font_char_from_lua(L, f, i, l_fonts, !no_math, is_nodefont); } } else if (lt == LUA_TSTRING) { const char *ss1 = lua_tostring(L, -2); if (lua_key_eq(ss1, left_boundary)) { - font_char_from_lua(L, f, left_boundarychar, l_fonts, !no_math); + font_char_from_lua(L, f, left_boundarychar, l_fonts, !no_math, is_nodefont); } else if (lua_key_eq(ss1, right_boundary)) { - font_char_from_lua(L, f, right_boundarychar, l_fonts, !no_math); + font_char_from_lua(L, f, right_boundarychar, l_fonts, !no_math, is_nodefont); } } lua_pop(L, 1); @@ -1844,7 +1854,7 @@ int characters_from_lua(lua_State * L, int f) set_charinfo_vert_variants(co, NULL); set_charinfo_hor_variants(co, NULL); } - font_char_from_lua(L, f, i, l_fonts, !no_math); + font_char_from_lua(L, f, i, l_fonts, !no_math, font_format(f) == node_format); } } lua_pop(L, 1); diff --git a/source/texk/web2c/luatexdir/font/texfont.c b/source/texk/web2c/luatexdir/font/texfont.c index 332a8a344..a25f8ef37 100644 --- a/source/texk/web2c/luatexdir/font/texfont.c +++ b/source/texk/web2c/luatexdir/font/texfont.c @@ -564,7 +564,7 @@ void set_charinfo_used(charinfo * ci, scaled val) void set_charinfo_index(charinfo * ci, scaled val) { - ci->index = (unsigned short) val; + ci->index = val; } void set_charinfo_name(charinfo * ci, char *val) diff --git a/source/texk/web2c/luatexdir/font/texfont.h b/source/texk/web2c/luatexdir/font/texfont.h index 2622b7a14..8f1b0bea7 100644 --- a/source/texk/web2c/luatexdir/font/texfont.h +++ b/source/texk/web2c/luatexdir/font/texfont.h @@ -85,7 +85,7 @@ typedef struct charinfo { liginfo *ligatures; /* ligature items */ kerninfo *kerns; /* kern items */ eight_bits *packets; /* virtual commands. */ - unsigned short index; /* CID index */ + halfword index; /* CID index or nodelist reference */ int remainder; /* spare value for odd items, could be union-ed with extensible */ scaled width; /* width */ scaled height; /* height */ @@ -190,6 +190,7 @@ typedef struct texfont { int _pdf_font_num; /* maps to a PDF resource ID */ str_number _pdf_font_attr; /* pointer to additional attributes */ + struct avl_table *_pdf_resources; } texfont; typedef enum { @@ -204,6 +205,7 @@ typedef enum { type3_format, truetype_format, opentype_format, + node_format, } font_formats; typedef enum { @@ -385,6 +387,9 @@ boolean cmp_font_area(int, str_number); # define pdf_font_attr(a) font_tables[a]->_pdf_font_attr # define set_pdf_font_attr(a,b) pdf_font_attr(a) = b +# define pdf_font_resources(a) font_tables[a]->_pdf_resources +# define set_pdf_font_resources(a,b) pdf_font_resources(a) = b + # define left_boundarychar -1 # define right_boundarychar -2 # define non_boundarychar -3 diff --git a/source/texk/web2c/luatexdir/font/writet3.c b/source/texk/web2c/luatexdir/font/writet3.c index 6121c24a1..6fd02da15 100644 --- a/source/texk/web2c/luatexdir/font/writet3.c +++ b/source/texk/web2c/luatexdir/font/writet3.c @@ -206,6 +206,28 @@ static boolean writepk(PDF pdf, internal_font_number f) return true; } +static boolean writet3nodes(PDF pdf, internal_font_number f) +{ + shipping_mode_e save_shipping_mode = global_shipping_mode; + int save_pdf_cur_form = pdf_cur_form; + scaledpos save_cur_page_size = pdf->page_size; + global_shipping_mode = SHIPPING_FORM; + t3_image_used = false; + is_pk_font = false; + t3_font_scale = by_one_bp / font_dsize(f); + for (int i = font_bc(f); i <= font_ec(f); i++) { + if (!pdf_char_marked(f, i)) + continue; + t3_char_widths[i] = (float) divide_scaled(ext_xn_over_d(get_charwidth(f, i), font_dsize(f), font_size(f)),one_hundred_bp,4); + t3_glyph_num++; + t3_char_procs[i] = char_index(f, i); + } + pdf->page_size = save_cur_page_size; + pdf_cur_form = save_pdf_cur_form; + global_shipping_mode = save_shipping_mode; + return true; +} + void writet3(PDF pdf, internal_font_number f) { int i; @@ -213,6 +235,7 @@ void writet3(PDF pdf, internal_font_number f) int wptr, eptr, cptr; int first_char, last_char; int pk_font_scale; + int procset = PROCSET_PDF; pdffloat pf; boolean is_notdef; t3_glyph_num = 0; @@ -222,11 +245,13 @@ void writet3(PDF pdf, internal_font_number f) t3_char_widths[i] = 0; } is_pk_font = false; - xfree(t3_buffer); - t3_curbyte = 0; - t3_size = 0; - if (!writepk(pdf, f)) - return; + if (font_format(f) == node_format) { + if (!writet3nodes(pdf, f)) + return; + } else { + if (!writepk(pdf, f)) + return; + } for (i = font_bc(f); i <= font_ec(f); i++) if (pdf_char_marked(f, i)) break; @@ -263,22 +288,85 @@ void writet3(PDF pdf, internal_font_number f) pdf_printf(pdf, "%g 0 0 %g 0 0", (double) t3_font_scale, (double) t3_font_scale); pdf_end_array(pdf); } - pdf_add_name(pdf, font_key[FONTBBOX1_CODE].pdfname); - pdf_begin_array(pdf); - pdf_add_int(pdf, (int) t3_b0); - pdf_add_int(pdf, (int) t3_b1); - pdf_add_int(pdf, (int) t3_b2); - pdf_add_int(pdf, (int) t3_b3); - pdf_end_array(pdf); + if (is_pk_font) { + pdf_add_name(pdf, font_key[FONTBBOX1_CODE].pdfname); + pdf_begin_array(pdf); + pdf_add_int(pdf, (int) t3_b0); + pdf_add_int(pdf, (int) t3_b1); + pdf_add_int(pdf, (int) t3_b2); + pdf_add_int(pdf, (int) t3_b3); + pdf_end_array(pdf); + } pdf_add_name(pdf, "Resources"); pdf_begin_dict(pdf); - pdf_add_name(pdf, "ProcSet"); - pdf_begin_array(pdf); - pdf_add_name(pdf, "PDF"); - if (t3_image_used) { - pdf_add_name(pdf, "ImageB"); + /*tex Generate font resources. */ + if (!is_pk_font && pdf_font_resources(f)) { + char s[64], *p; + pdf_object_list *ol, *ol1; + if ((ol = get_resources_list(pdf_font_resources(f), obj_type_font))) { + pdf_add_name(pdf, "Font"); + pdf_begin_dict(pdf); + while (ol != NULL) { + p = s; + p += snprintf(p, 20, "F%i", obj_info(pdf, ol->info)); + if (pdf->resname_prefix != NULL) + p += snprintf(p, 20, "%s", pdf->resname_prefix); + pdf_dict_add_ref(pdf, s, ol->info); + ol = ol->link; + } + pdf_end_dict(pdf); + procset |= PROCSET_TEXT; + } + /*tex Generate |XObject| resources. */ + ol = get_resources_list(pdf_font_resources(f), obj_type_xform); + ol1 = get_resources_list(pdf_font_resources(f), obj_type_ximage); + if (ol != NULL || ol1 != NULL) { + pdf_add_name(pdf, "XObject"); + pdf_begin_dict(pdf); + while (ol != NULL) { + p = s; + p += snprintf(p, 20, "Fm%i", obj_info(pdf, ol->info)); + if (pdf->resname_prefix != NULL) + p += snprintf(p, 20, "%s", pdf->resname_prefix); + pdf_dict_add_ref(pdf, s, ol->info); + ol = ol->link; + } + while (ol1 != null) { + p = s; + p += snprintf(p, 20, "Im%i", obj_info(pdf, ol1->info)); + if (pdf->resname_prefix != NULL) + p += snprintf(p, 20, "%s", pdf->resname_prefix); + pdf_dict_add_ref(pdf, s, ol1->info); + procset |= img_procset(idict_array[obj_data_ptr(pdf, ol1->info)]); + ol1 = ol1->link; + } + pdf_end_dict(pdf); + } + /*tex Generate |ProcSet| in version 1.*/ + if (pdf->major_version == 1) { + pdf_add_name(pdf, "ProcSet"); + pdf_begin_array(pdf); + if ((procset & PROCSET_PDF) != 0) + pdf_add_name(pdf, "PDF"); + if ((procset & PROCSET_TEXT) != 0) + pdf_add_name(pdf, "Text"); + if ((procset & PROCSET_IMAGE_B) != 0) + pdf_add_name(pdf, "ImageB"); + if ((procset & PROCSET_IMAGE_C) != 0) + pdf_add_name(pdf, "ImageC"); + if ((procset & PROCSET_IMAGE_I) != 0) + pdf_add_name(pdf, "ImageI"); + pdf_end_array(pdf); + } + } else { + pdf_add_name(pdf, "ProcSet"); + pdf_begin_array(pdf); + pdf_add_name(pdf, "PDF"); + if (t3_image_used) { + pdf_add_name(pdf, "ImageB"); + } + pdf_end_array(pdf); } - pdf_end_array(pdf); pdf_end_dict(pdf); pdf_dict_add_int(pdf, "FirstChar", first_char); pdf_dict_add_int(pdf, "LastChar", last_char); @@ -293,16 +381,10 @@ void writet3(PDF pdf, internal_font_number f) /*tex The |Widths| array: */ pdf_begin_obj(pdf, wptr, OBJSTM_ALWAYS); pdf_begin_array(pdf); - if (is_pk_font) { - for (i = first_char; i <= last_char; i++) { - setpdffloat(pf, (int64_t) t3_char_widths[i], 2); - print_pdffloat(pdf, pf); - pdf_out(pdf, ' '); - } - } else { - for (i = first_char; i <= last_char; i++) { - pdf_add_int(pdf, (int) t3_char_widths[i]); - } + for (i = first_char; i <= last_char; i++) { + setpdffloat(pf, (int64_t) t3_char_widths[i], 2); + print_pdffloat(pdf, pf); + pdf_out(pdf, ' '); } pdf_end_array(pdf); pdf_end_obj(pdf); diff --git a/source/texk/web2c/luatexdir/pdf/pdffont.c b/source/texk/web2c/luatexdir/pdf/pdffont.c index 1e1f0f8d9..4cd496cb3 100644 --- a/source/texk/web2c/luatexdir/pdf/pdffont.c +++ b/source/texk/web2c/luatexdir/pdf/pdffont.c @@ -165,6 +165,9 @@ void pdf_init_font(PDF pdf, internal_font_number f) } i = obj_link(pdf, i); } + if(font_format(f) == node_format) { + set_pdf_font_resources(f, NULL); + } /*tex Create a new font object for |f|: */ l = pdf_create_obj(pdf, obj_type_font, f); pdf_use_font(f, l); diff --git a/source/texk/web2c/luatexdir/pdf/pdfgen.c b/source/texk/web2c/luatexdir/pdf/pdfgen.c index 3d37102b2..52227489b 100644 --- a/source/texk/web2c/luatexdir/pdf/pdfgen.c +++ b/source/texk/web2c/luatexdir/pdf/pdfgen.c @@ -811,19 +811,66 @@ void addto_page_resources(PDF pdf, pdf_obj_type t, int k) } } -pdf_object_list *get_page_resources_list(PDF pdf, pdf_obj_type t) +static void merge_page_resources(PDF pdf, pdf_obj_type t, struct avl_table **destination) +{ + pr_entry *pr, tmp, *src; + void **pp; + pdf_object_list *p, *item = NULL, *tail = NULL; + tmp.obj_type = t; + if (!pdf->page_resources || !pdf->page_resources->resources_tree) return; + src = (pr_entry *) avl_find(pdf->page_resources->resources_tree, &tmp); + if (!src) return; + if (*destination == NULL) { + *destination = avl_create(comp_page_resources, NULL, &avl_xallocator); + if (*destination == NULL) + formatted_error("pdf backend","marge_page_resources(): avl_create() page_resource_tree failed"); + } + pr = (pr_entry *) avl_find(*destination, &tmp); + if (pr == NULL) { + pr = xtalloc(1, pr_entry); + pr->obj_type = t; + pr->list = NULL; + pp = avl_probe(*destination, pr); + if (pp == NULL) + formatted_error("pdf backend","addto_page_resources(): avl_probe() out of memory in insertion"); + } + if (pr->list == NULL) { + pr->list = src->list; + src->list = NULL; + } else { + while (src->list) { + item = src->list; + src->list = item->link; + for (p = pr->list; p->info != item->info && p->link != tail; p = p->link); + if (p->info == item->info) { + free(item); + } else { + if (tail == NULL) tail = p; + item->link = NULL; + p->link = item; + } + } + } +} + +pdf_object_list *get_resources_list(struct avl_table *rt, pdf_obj_type t) { - pdf_resource_struct *re = pdf->page_resources; pr_entry *pr, tmp; - if (re == NULL || re->resources_tree == NULL) - return NULL; tmp.obj_type = t; - pr = (pr_entry *) avl_find(re->resources_tree, &tmp); + pr = (pr_entry *) avl_find(rt, &tmp); if (pr == NULL) return NULL; return pr->list; } +pdf_object_list *get_page_resources_list(PDF pdf, pdf_obj_type t) +{ + pdf_resource_struct *re = pdf->page_resources; + if (re == NULL || re->resources_tree == NULL) + return NULL; + return get_resources_list(re->resources_tree, t); +} + static void reset_page_resources(PDF pdf) { pdf_resource_struct *re = pdf->page_resources; @@ -1640,7 +1687,8 @@ void pdf_begin_page(PDF pdf) pdf->page_resources = xtalloc(1, pdf_resource_struct); pdf->page_resources->resources_tree = NULL; } - pdf->page_resources->last_resources = pdf_create_obj(pdf, obj_type_others, 0); + if (global_shipping_mode != SHIPPING_GLYPH) + pdf->page_resources->last_resources = pdf_create_obj(pdf, obj_type_others, 0); reset_page_resources(pdf); if (global_shipping_mode == SHIPPING_PAGE) { @@ -1652,52 +1700,54 @@ void pdf_begin_page(PDF pdf) pdf->last_thread = null; pdf_begin_dict(pdf); } else { - xform_type = obj_xform_type(pdf, pdf_cur_form) ; pdf_begin_obj(pdf, pdf_cur_form, OBJSTM_NEVER); pdf->last_stream = pdf_cur_form; /*tex Write out the |Form| stream header */ pdf_begin_dict(pdf); - if (xform_type == 0) { - pdf_dict_add_name(pdf, "Type", "XObject"); - pdf_dict_add_name(pdf, "Subtype", "Form"); - pdf_dict_add_int(pdf, "FormType", 1); - } - xform_attributes = pdf_xform_attr; - /*tex Now stored in the object: */ - form_margin = obj_xform_margin(pdf, pdf_cur_form); - if (xform_attributes != null) - pdf_print_toks(pdf, xform_attributes); - if (obj_xform_attr(pdf, pdf_cur_form) != null) { - pdf_print_toks(pdf, obj_xform_attr(pdf, pdf_cur_form)); - delete_token_ref(obj_xform_attr(pdf, pdf_cur_form)); - set_obj_xform_attr(pdf, pdf_cur_form, null); - } - if (obj_xform_attr_str(pdf, pdf_cur_form) != null) { - lua_pdf_literal(pdf, obj_xform_attr_str(pdf, pdf_cur_form),1); - luaL_unref(Luas, LUA_REGISTRYINDEX, obj_xform_attr_str(pdf, pdf_cur_form)); - set_obj_xform_attr_str(pdf, pdf_cur_form, null); - } - if (xform_type == 0 || xform_type == 1 || xform_type == 3) { - pdf_add_name(pdf, "BBox"); - pdf_begin_array(pdf); - pdf_add_bp(pdf, -form_margin); - pdf_add_bp(pdf, -form_margin); - pdf_add_bp(pdf, pdf->page_size.h + form_margin); - pdf_add_bp(pdf, pdf->page_size.v + form_margin); - pdf_end_array(pdf); - } - if (xform_type == 0 || xform_type == 2 || xform_type == 3) { - pdf_add_name(pdf, "Matrix"); - pdf_begin_array(pdf); - pdf_add_int(pdf, 1); - pdf_add_int(pdf, 0); - pdf_add_int(pdf, 0); - pdf_add_int(pdf, 1); - pdf_add_int(pdf, 0); - pdf_add_int(pdf, 0); - pdf_end_array(pdf); + if(global_shipping_mode == SHIPPING_FORM) { + xform_type = obj_xform_type(pdf, pdf_cur_form) ; + if (xform_type == 0) { + pdf_dict_add_name(pdf, "Type", "XObject"); + pdf_dict_add_name(pdf, "Subtype", "Form"); + pdf_dict_add_int(pdf, "FormType", 1); + } + xform_attributes = pdf_xform_attr; + /*tex Now stored in the object: */ + form_margin = obj_xform_margin(pdf, pdf_cur_form); + if (xform_attributes != null) + pdf_print_toks(pdf, xform_attributes); + if (obj_xform_attr(pdf, pdf_cur_form) != null) { + pdf_print_toks(pdf, obj_xform_attr(pdf, pdf_cur_form)); + delete_token_ref(obj_xform_attr(pdf, pdf_cur_form)); + set_obj_xform_attr(pdf, pdf_cur_form, null); + } + if (obj_xform_attr_str(pdf, pdf_cur_form) != null) { + lua_pdf_literal(pdf, obj_xform_attr_str(pdf, pdf_cur_form),1); + luaL_unref(Luas, LUA_REGISTRYINDEX, obj_xform_attr_str(pdf, pdf_cur_form)); + set_obj_xform_attr_str(pdf, pdf_cur_form, null); + } + if (xform_type == 0 || xform_type == 1 || xform_type == 3) { + pdf_add_name(pdf, "BBox"); + pdf_begin_array(pdf); + pdf_add_bp(pdf, -form_margin); + pdf_add_bp(pdf, -form_margin); + pdf_add_bp(pdf, pdf->page_size.h + form_margin); + pdf_add_bp(pdf, pdf->page_size.v + form_margin); + pdf_end_array(pdf); + } + if (xform_type == 0 || xform_type == 2 || xform_type == 3) { + pdf_add_name(pdf, "Matrix"); + pdf_begin_array(pdf); + pdf_add_int(pdf, 1); + pdf_add_int(pdf, 0); + pdf_add_int(pdf, 0); + pdf_add_int(pdf, 1); + pdf_add_int(pdf, 0); + pdf_add_int(pdf, 0); + pdf_end_array(pdf); + } + pdf_dict_add_ref(pdf, "Resources", pdf->page_resources->last_resources); } - pdf_dict_add_ref(pdf, "Resources", pdf->page_resources->last_resources); } /*tex Start a stream of page or form contents: */ pdf_dict_add_streaminfo(pdf); @@ -1875,6 +1925,25 @@ void pdf_end_page(PDF pdf) } ol = ol->link; } + ol = get_page_resources_list(pdf, obj_type_glyph); + while (ol != NULL) { + if (!is_obj_written(pdf, ol->info)) { + save_pdf_cur_form = pdf_cur_form; + pdf_cur_form = ol->info; + save_cur_page_size = pdf->page_size; + save_shipping_mode = global_shipping_mode; + pdf->page_resources = &local_page_resources; + local_page_resources.resources_tree = NULL; + ship_out(pdf, obj_xform_box(pdf, pdf_cur_form), SHIPPING_GLYPH); + /*tex Restore the page size and page resources. */ + pdf->page_size = save_cur_page_size; + global_shipping_mode = save_shipping_mode; + destroy_page_resources_tree(pdf); + pdf->page_resources = res_p; + pdf_cur_form = save_pdf_cur_form; + } + ol = ol->link; + } /*tex Write out pending images. */ ol = get_page_resources_list(pdf, obj_type_ximage); while (ol != NULL) { @@ -1937,6 +2006,13 @@ void pdf_end_page(PDF pdf) /*tex Write out \PDF\ bead rectangle specifications. */ print_bead_rectangles(pdf); } + if (global_shipping_mode == SHIPPING_GLYPH) { + /*tex Merge resources into font resources. */ + merge_page_resources(pdf, obj_type_font, &pdf_font_resources(obj_xform_type(pdf, pdf_cur_form))); + merge_page_resources(pdf, obj_type_xform, &pdf_font_resources(obj_xform_type(pdf, pdf_cur_form))); + merge_page_resources(pdf, obj_type_ximage, &pdf_font_resources(obj_xform_type(pdf, pdf_cur_form))); + return; + } /*tex Write out resources dictionary. */ pdf_begin_obj(pdf, res_p->last_resources, OBJSTM_ALWAYS); pdf_begin_dict(pdf); diff --git a/source/texk/web2c/luatexdir/pdf/pdfgen.h b/source/texk/web2c/luatexdir/pdf/pdfgen.h index 00df7f36e..69b3a4966 100644 --- a/source/texk/web2c/luatexdir/pdf/pdfgen.h +++ b/source/texk/web2c/luatexdir/pdf/pdfgen.h @@ -68,6 +68,7 @@ be the first written bytes. typedef enum { /* needs pdf_prefix */ NOT_SHIPPING, SHIPPING_PAGE, + SHIPPING_GLYPH, SHIPPING_FORM } shipping_mode_e; @@ -179,6 +180,7 @@ extern void strbuf_free(strbuf_s * b); extern void addto_page_resources(PDF pdf, pdf_obj_type t, int k); extern pdf_object_list *get_page_resources_list(PDF pdf, pdf_obj_type t); +extern pdf_object_list *get_resources_list(struct avl_table *rt, pdf_obj_type t); extern void pdf_out_block(PDF pdf, const char *s, size_t n); diff --git a/source/texk/web2c/luatexdir/pdf/pdfglyph.c b/source/texk/web2c/luatexdir/pdf/pdfglyph.c index c7cf04392..94e2cc856 100644 --- a/source/texk/web2c/luatexdir/pdf/pdfglyph.c +++ b/source/texk/web2c/luatexdir/pdf/pdfglyph.c @@ -287,3 +287,28 @@ void pdf_place_glyph(PDF pdf, internal_font_number f, int c, int ex) /*tex Also known as |adv_char_width()|: */ p->cw.m += pdf_char_width(p, p->f_pdf, c); } + +void pdf_ship_node_char(PDF pdf, internal_font_number f, int c) { + int objnum; + if (pdf_font_num(f) < 0) { + pdf_mark_char(-pdf_font_num(f), c); + return; + } + if (!char_exists(f, c)) return; + if (!pdf_char_marked(f, c)) { + pdf->xform_count++; + objnum = pdf_create_obj(pdf, obj_type_glyph, pdf->xform_count); + set_obj_data_ptr(pdf, objnum, pdf_get_mem(pdf, pdfmem_xform_size)); + set_obj_xform_type(pdf, objnum, f); + set_obj_xform_margin(pdf, objnum, pdf_xform_margin); + assert(char_index(f, c) >= 0); + if (char_index(f, c) == null) + normal_error("pdf backend", "a node glyph needs a node"); + set_obj_xform_box(pdf, objnum, char_index(f, c)); + set_charinfo_index(get_charinfo(f, c), objnum); + if (global_shipping_mode == NOT_SHIPPING) + ship_out(pdf, char_index(f, c), SHIPPING_GLYPH); + else + addto_page_resources(pdf, obj_type_glyph, objnum); + } +} diff --git a/source/texk/web2c/luatexdir/pdf/pdfglyph.h b/source/texk/web2c/luatexdir/pdf/pdfglyph.h index 2d04e944c..29430bfd2 100644 --- a/source/texk/web2c/luatexdir/pdf/pdfglyph.h +++ b/source/texk/web2c/luatexdir/pdf/pdfglyph.h @@ -21,6 +21,7 @@ #ifndef PDFGLYPH_H # define PDFGLYPH_H +void pdf_ship_node_char(PDF pdf, internal_font_number f, int c); void end_chararray(PDF pdf); void end_charmode(PDF pdf); void pdf_place_glyph(PDF pdf, internal_font_number f, int c, int ex); diff --git a/source/texk/web2c/luatexdir/pdf/pdfshipout.c b/source/texk/web2c/luatexdir/pdf/pdfshipout.c index 084efc086..4aabe5a00 100644 --- a/source/texk/web2c/luatexdir/pdf/pdfshipout.c +++ b/source/texk/web2c/luatexdir/pdf/pdfshipout.c @@ -196,7 +196,7 @@ void ship_out(PDF pdf, halfword p, shipping_mode_e shipping_mode) cur.v = height(p); synch_pos_with_cur(pdf->posstruct, &refpoint, cur); } else { - /*tex We're shipping out a |/Form|. */ + /*tex We're shipping out a |/Form| or a node font glyph. */ pdf->posstruct->dir = box_dir(p); switch (pdf->posstruct->dir) { case dir_TLT: @@ -217,11 +217,11 @@ void ship_out(PDF pdf, halfword p, shipping_mode_e shipping_mode) switch (pdf->posstruct->dir) { case dir_TLT: pdf->posstruct->pos.h = 0; - pdf->posstruct->pos.v = depth(p); + pdf->posstruct->pos.v = global_shipping_mode == SHIPPING_FORM ? depth(p) : 0; break; case dir_TRT: pdf->posstruct->pos.h = width(p); - pdf->posstruct->pos.v = depth(p); + pdf->posstruct->pos.v = global_shipping_mode == SHIPPING_FORM ? depth(p) : 0; break; case dir_LTL: pdf->posstruct->pos.h = height(p); @@ -233,7 +233,7 @@ void ship_out(PDF pdf, halfword p, shipping_mode_e shipping_mode) break; default: pdf->posstruct->pos.h = 0; - pdf->posstruct->pos.v = depth(p); + pdf->posstruct->pos.v = global_shipping_mode == SHIPPING_FORM ? depth(p) : 0; normal_warning("pdf backend","bad page direction, assuming TLT, case 5"); } } diff --git a/source/texk/web2c/luatexdir/pdf/pdftypes.h b/source/texk/web2c/luatexdir/pdf/pdftypes.h index 67ffcbecb..a2660538b 100644 --- a/source/texk/web2c/luatexdir/pdf/pdftypes.h +++ b/source/texk/web2c/luatexdir/pdf/pdftypes.h @@ -218,11 +218,12 @@ typedef enum { obj_type_bead = 15, /* thread bead objects */ obj_type_beads = 16, /* /B objects (array of bead objects) */ obj_type_objstm = 17, /* /ObjStm objects */ - obj_type_others = 18 /* any other objects (also not linked in any list) */ + obj_type_glyph = 18, /* Type 3 charstring objects */ + obj_type_others = 19 /* any other objects (also not linked in any list) */ } pdf_obj_type; # define HEAD_TAB_MAX 6 /* obj_type_thread */ -# define PDF_OBJ_TYPE_MAX 18 /* obj_type_others */ +# define PDF_OBJ_TYPE_MAX 19 /* obj_type_others */ typedef struct pdf_resource_struct_ { struct avl_table *resources_tree; diff --git a/source/texk/web2c/luatexdir/ptexlib.h b/source/texk/web2c/luatexdir/ptexlib.h index f63f480b0..9de7624bb 100644 --- a/source/texk/web2c/luatexdir/ptexlib.h +++ b/source/texk/web2c/luatexdir/ptexlib.h @@ -313,7 +313,12 @@ extern boolean get_callback(lua_State * L, int i); /* Additions to texmfmp.h for pdfTeX */ /* mark a char in font */ -# define pdf_mark_char(f,c) set_char_used(f,c,true) +# define pdf_mark_char(f,c) do { \ + if(font_format(f) == node_format) { \ + pdf_ship_node_char(static_pdf, f, c); \ + } \ + set_char_used(f,c,true); \ +} while (0) /* test whether a char in font is marked */ # define pdf_char_marked char_used -- 2.23.0