[PATCH v3] pdftex - Add support for encfile and \pdfgentounicode for PK fonts
Pali Rohár <[email protected]>
| Newsgroups | gmane.comp.tex.pdftex |
|---|---|
| Message-ID | <201607061426.20338@pali> |
... continued thread "[pdftex] pdftex - Encoding for metafont PK fonts"
This patch allows to specify encoding file also for bitmap PK fonts
(generated by MetaFont) and add support for \pdfgentounicode primitive
for these fonts.
Example for csb12 (CSFonts, Latin 2 encoding):
\nopagenumbers
\pdfmapline{+csb12 <csr.enc}
\pdfglyphtounicode{ccaron}{010D}
\pdfgentounicode=1
\font\csb=csb12
\csb \char232
\bye
Char 232 (0xE8) in font csb12 is 'č' (LATIN SMALL LETTER C WITH CARON)
and glyph name for 'č' is /ccaron. Unicode character is 0+010D.
Note that U+OOE8 (decimal 232) is 'è' (LATIN SMALL LETTER E WITH GRAVE)
which is reason why encoding file (csr.enc) is needed. Unicode is
extension of Latin 1 (character positions 127-255 are same) so this is
reason why Latin 1 PK fonts works fine without encoding files...
In V3 version of patch I added check for duplicate glyph names to
prevent generating incorrect PDF files. Duplicates of glyph names are
not used and default glyph name used by pdftex "\a<number>" is used as
before. And I added small extension to pdftex-t.tex documentation as
Karl Berry wanted.
--
Pali Rohár
[email protected]
pdftex-pkfonts-encfile-tounicode-v3.patch
(text/x-patch, 6 KB)
Index: texlive-bin-2012.20120628/texk/web2c/pdftexdir/mapfile.c
===================================================================
--- texlive-bin-2012.20120628.orig/texk/web2c/pdftexdir/mapfile.c 2012-04-12 18:48:24.000000000 +0200
+++ texlive-bin-2012.20120628/texk/web2c/pdftexdir/mapfile.c 2016-06-26 22:39:36.102270848 +0200
@@ -288,11 +288,11 @@
/* do not set variable |a| as this entry will be still accepted */
}
- /* if both ps_name and font file are missing, drop this entry */
- if (fm->ps_name == NULL && !is_fontfile(fm)) {
+ /* if ps_name, font file and enc file are missing, drop this entry */
+ if (fm->ps_name == NULL && !is_fontfile(fm) && !is_reencoded(fm)) {
if (warn)
pdftex_warn
- ("invalid entry for `%s': both ps_name and font file missing",
+ ("invalid entry for `%s': ps_name, font file and enc file missing",
fm->tfm_name);
a += 1;
}
Index: texlive-bin-2012.20120628/texk/web2c/pdftexdir/writefont.c
===================================================================
--- texlive-bin-2012.20120628.orig/texk/web2c/pdftexdir/writefont.c 2011-04-29 02:06:36.000000000 +0200
+++ texlive-bin-2012.20120628/texk/web2c/pdftexdir/writefont.c 2016-06-26 22:38:17.129390428 +0200
@@ -664,7 +664,7 @@
fm_entry *fm;
fm = hasfmentry(f) ? (fm_entry *) pdffontmap[f] : NULL;
if (fm == NULL || (fm->ps_name == NULL && fm->ff_name == NULL))
- writet3(font_objnum, f);
+ writet3(fm, font_objnum, f);
else
create_fontdictionary(fm, font_objnum, f);
}
Index: texlive-bin-2012.20120628/texk/web2c/pdftexdir/ptexlib.h
===================================================================
--- texlive-bin-2012.20120628.orig/texk/web2c/pdftexdir/ptexlib.h 2012-05-20 01:57:09.000000000 +0200
+++ texlive-bin-2012.20120628/texk/web2c/pdftexdir/ptexlib.h 2016-06-26 22:32:28.261532200 +0200
@@ -315,7 +315,7 @@
extern void t1_free(void);
/* writet3.c */
-extern void writet3(int, internalfontnumber);
+extern void writet3(fm_entry *, int, internalfontnumber);
extern scaled getpkcharwidth(internalfontnumber, scaled);
/* writettf.c */
Index: texlive-bin-2012.20120628/texk/web2c/pdftexdir/writet3.c
===================================================================
--- texlive-bin-2012.20120628.orig/texk/web2c/pdftexdir/writet3.c 2011-04-29 02:06:36.000000000 +0200
+++ texlive-bin-2012.20120628/texk/web2c/pdftexdir/writet3.c 2016-07-06 13:19:19.210650278 +0200
@@ -254,7 +254,30 @@
return true;
}
-void writet3(int objnum, internalfontnumber f)
+static void remove_duplicate_glyph_names(char **g, const char *encname)
+{
+ struct avl_table *gl_tree;
+ char *aa;
+ int i;
+ gl_tree = avl_create(comp_string_entry, NULL, &avl_xallocator);
+ assert(gl_tree != NULL);
+ for (i = 0; i < 256; i++) {
+ if (g[i] == notdef)
+ continue;
+ aa = (char *) avl_find(gl_tree, g[i]);
+ if (aa == NULL) {
+ aa = (char *) avl_probe(gl_tree, g[i]);
+ assert(aa != NULL);
+ } else {
+ pdftex_warn("duplicate glyph name `%s' at position %d in file `%s'", g[i], i, encname);
+ xfree(g[i]);
+ g[i] = (char *) notdef;
+ }
+ }
+ avl_destroy(gl_tree, NULL);
+}
+
+void writet3(fm_entry * fm, int objnum, internalfontnumber f)
{
static char t3_font_scale_str[] = "\\pdffontscale";
int i;
@@ -262,12 +285,19 @@
int first_char, last_char;
integer pk_font_scale;
boolean is_notdef;
+ fe_entry *fe;
+ char **glyph_names;
+ integer tounicode_objnum;
t3_glyph_num = 0;
t3_image_used = false;
for (i = 0; i < 256; i++) {
t3_char_procs[i] = 0;
t3_char_widths[i] = 0;
}
+ fe = fm ? get_fe_entry(fm->encname) : NULL;
+ glyph_names = fe ? fe->glyph_names : NULL;
+ if (glyph_names)
+ remove_duplicate_glyph_names(glyph_names, fm->encname);
packfilename(fontname[f], getnullstr(), maketexstring(".pgc"));
cur_file_name = makecstring(makenamestring());
is_pk_font = false;
@@ -298,6 +328,11 @@
if (pdfcharmarked(f, i))
break;
last_char = i;
+ /* write ToUnicode entry if needed */
+ if (fixedgentounicode > 0 && !pdffontnobuiltintounicode[f] && fe != NULL)
+ tounicode_objnum = write_tounicode(glyph_names, fm->tfm_name, fe->name);
+ else
+ tounicode_objnum = 0;
pdfbegindict(objnum, 1); /* Type 3 font dictionary */
pdf_puts("/Type /Font\n/Subtype /Type3\n");
pdf_printf("/Name /F%i\n", (int) f);
@@ -344,7 +379,10 @@
pdf_printf("/%s", notdef);
is_notdef = true;
} else {
- pdf_printf("/a%i", first_char);
+ if (glyph_names && glyph_names[first_char] && glyph_names[first_char] != notdef)
+ pdf_printf("/%s", glyph_names[first_char]);
+ else
+ pdf_printf("/a%i", first_char);
is_notdef = false;
}
for (i = first_char + 1; i <= last_char; i++) {
@@ -358,15 +396,23 @@
pdf_printf(" %i", i);
is_notdef = false;
}
- pdf_printf("/a%i", i);
+ if (glyph_names && glyph_names[i] && glyph_names[i] != notdef)
+ pdf_printf("/%s", glyph_names[i]);
+ else
+ pdf_printf("/a%i", i);
}
}
pdf_puts("]\n");
+ if (tounicode_objnum != 0)
+ pdf_printf("/ToUnicode %i 0 R\n", (int) tounicode_objnum);
pdfenddict();
pdfbegindict(cptr, 1); /* CharProcs dictionary */
for (i = first_char; i <= last_char; i++)
if (t3_char_procs[i] != 0)
- pdf_printf("/a%i %i 0 R\n", (int) i, (int) t3_char_procs[i]);
+ if (glyph_names && glyph_names[i] && glyph_names[i] != notdef)
+ pdf_printf("/%s %i 0 R\n", glyph_names[i], (int) t3_char_procs[i]);
+ else
+ pdf_printf("/a%i %i 0 R\n", (int) i, (int) t3_char_procs[i]);
pdfenddict();
t3_close();
tex_printf(">");
pdftex-t.tex-pkfonts-encfile.patch
(text/x-patch, 541 B)
--- pdftex-t.tex.orig 2016-07-06 13:34:07.018232240 +0200
+++ pdftex-t.tex 2016-07-06 13:57:45.939143342 +0200
@@ -1623,6 +1623,10 @@ field may be omitted if you are sure tha
correct built||in encoding. In general this option is highly recommended,
and it is {\em required} when subsetting a TrueType font.
+The encoding file can be specified also for bitmap PK fonts. In this case
+it assigns glyph names from encoding vector which can be used for
+\type{\pdfgentounicode} primitive.
+
\stopdescription
\startdescription {fontfile}
signature.asc
(application/pgp-signature, 198 B)
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iEYEABECAAYFAld8+OwACgkQi/DJPQPkQ1Ld8wCZAawy0QMTPBSg5tW/mjqLRS2S axwAn2205CcNGp39gotJC7ySsmsbF7gZ =4iXi -----END PGP SIGNATURE-----